home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-12-31 | 129.1 KB | 3,372 lines | [TEXT/R*ch] |
- C.S.M.P. Digest Mon, 14 Nov 94 Volume 3 : Issue 67
-
- Today's Topics:
-
- (Q) AppleScript & XCMD's
- Can anyone help me with the Time Manager?
- Dynamic Dialogs?
- How to install your own templates using Macsbug 6.5d6???
- IM: Networking book question
- INIT Writing FAQ [1-3]
- INIT Writing FAQ [2-3]
- INIT Writing FAQ [3-3]
- Linking 68k object files to PPC program
- Network Programming
- Stuck in SyncWait again
- having trouble with AEInteractWithUser & drag manager
-
-
-
- The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier
- (pottier@clipper.ens.fr).
-
- The digest is a collection of article threads from the internet newsgroup
- comp.sys.mac.programmer. It is designed for people who read c.s.m.p. semi-
- regularly and want an archive of the discussions. If you don't know what a
- newsgroup is, you probably don't have access to it. Ask your systems
- administrator(s) for details. If you don't have access to news, you may
- still be able to post messages to the group by using a mail server like
- anon.penet.fi (mail help@anon.penet.fi for more information).
-
- Each issue of the digest contains one or more sets of articles (called
- threads), with each set corresponding to a 'discussion' of a particular
- subject. The articles are not edited; all articles included in this digest
- are in their original posted form (as received by our news server at
- nef.ens.fr). Article threads are not added to the digest until the last
- article added to the thread is at least two weeks old (this is to ensure that
- the thread is dead before adding it to the digest). Article threads that
- consist of only one message are generally not included in the digest.
-
- The digest is officially distributed by two means, by email and ftp.
-
- If you want to receive the digest by mail, send email to listserv@ens.fr
- with no subject and one of the following commands as body:
- help Sends you a summary of commands
- subscribe csmp-digest Your Name Adds you to the mailing list
- signoff csmp-digest Removes you from the list
- Once you have subscribed, you will automatically receive each new
- issue as it is created.
-
- The official ftp info is //ftp.dartmouth.edu/pub/csmp-digest.
- Questions related to the ftp site should be directed to
- scott.silver@dartmouth.edu. Currently no previous volumes of the CSMP
- digest are available there.
-
- Also, the digests are available to WAIS users. To search back issues
- with WAIS, use comp.sys.mac.programmer.src. With Mosaic, use
- http://www.wais.com/wais-dbs/comp.sys.mac.programmer.html.
-
-
- -------------------------------------------------------
-
- >From Tom_Brodhurst-Hill@intouch.mpx.com.au (Tom Brodhurst-Hill)
- Subject: (Q) AppleScript & XCMD's
- Date: 31 Oct 1994 19:07:41 GMT
- Organization: MacInTouch BBS
-
- Can anyone tell me whether XCMD's (typically for HyperCard) can be included
- in
- and accessed by a compiled AppleScript application, without running a
- separate HyperCard process?
- Thanks,
- Tom
- please email to tombh@intouch.mpx.com.au
- and post too for others.
- MacInTouch BBS
- info@intouch.mpx.com.au Ph. 61 2 541 1287 BBS. 61 2 541 0799
- *** Sent by FirstClass the graphical email system by SoftArc. Inc. ***
-
- +++++++++++++++++++++++++++
-
- >From lai@apple.com (Ed Lai)
- Date: Mon, 31 Oct 1994 17:20:39 GMT
- Organization: Apple
-
- In article <29224926.900353@intouch.intouch.mpx.com.au>,
- Tom_Brodhurst-Hill@intouch.mpx.com.au (Tom Brodhurst-Hill) wrote:
-
- > Can anyone tell me whether XCMD's (typically for HyperCard) can be included
- in
- > and accessed by a compiled AppleScript application, without running a
- > separate HyperCard process?
- > Thanks,
- > Tom
- > please email to tombh@intouch.mpx.com.au
- > and post too for others.
- > MacInTouch BBS
- > info@intouch.mpx.com.au Ph. 61 2 541 1287 BBS. 61 2 541 0799
- > *** Sent by FirstClass the graphical email system by SoftArc. Inc. ***
-
- It depends on the XCMD, a lot of them can be used, but if they are
- very dependent on HyperCard specifc callback or globals, then they
- cannot.
-
- Try to download the XCMD OSAX.
-
- Generally the place to look for AppleScript related stuff is in
- gaea.kgs.ukans.edu.
-
- If it is just for the XCMD OSAX, you may try ftp.apple.com in
- /pub/lai/osax.
-
- It is an adaptor for AppleScript to use XCMDs. It also comes installed
- with a number of XCMDs by Rinaldi as examples.
-
- In theory you can try it with any other XCMD/XFCNs you got. However to
- do that requires writing certain resources and that is not a easy
- job if you are doing it the first time.
-
- --
- /* Disclaimer: All statments and opinions expressed are my own */
- /* Edmund K. Lai */
- /* Apple Computer, MS303-3A */
- /* 20525 Mariani Ave, */
- /* Cupertino, CA 95014 */
- /* (408)974-6272 */
- zW@h9cOi
-
- ---------------------------
-
- >From anthonym@puree.ugcs.caltech.edu (Anthony Molinaro)
- Subject: Can anyone help me with the Time Manager?
- Date: 21 Oct 1994 08:09:59 GMT
- Organization: California Institute of Technology, Pasadena
-
-
- I worked on this piece of code for a friend using Symatec
- THINK C which turns on the power to a digital I/O board,
- delays for a certain number of ticks, and then turns the
- power off. This was my first time programming on a Macintosh
- and so I had to search a little bit to find out about Delay.
- Now, he tells me he needs a delay time smaller than one tick.
- I know that the time manager can do this but I have been
- unable to get it to work. I guess my confusion arises in the
- type declarations and getting all of the types to match for
- functions InsXTime(), PrimeTime(), and such. The Inside
- Macintosh doesn't have any examples in C and I have not been
- able to accurately port the Pascal functions with the proper
- type settings. My midterms are quickly approaching but I
- promised I would help him out, so any help that anyone could
- give would be .
-
-
-
- /* Here is the original code */
-
- void Play(int note, unsigned long time)
- { long finalTicks;
- short error;
-
- /* turn on power for port,line: portout, lineout */
- error = DIG_Out_Line(4, notes[note].portout, notes[note].line, 1);
- chkerr("DIG_Out_Line",error);
-
- /* if power is on delay */
- if(error == 0)
- Delay(time,&finalTicks);
-
- /* turn off power */
- error = DIG_Out_Line(4, notes[note].portout, notes[note].line, 0);
- chkerr("DIG_Out_Line",error);
- }
-
- /* Here is what I tryed */
- /* global variables */
-
- int note;
- TMTask tblah;
-
- pascal void MyTimeTask(void)
- { DIG_Out_Line(4, notes[note].portout, notes[note].line, 0);
- }
-
- void MyDelay(unsigned long time)
- { tblah.tmAddr = &MyTimeTask();
- tblah.tmWakeUp = 0;
- tblah.tmReserved = 0;
- InsXTime(&tblah);
- PrimeTime(&tblah,time);
- }
-
- This didn't work, and I don't have a lot of time to figure out
- why, so if anyone has any ideas I'm open to them. Thanks in
- advance. Reply through e-mail if possible.
-
- =====================================================================
- Anthony Molinaro
- anthonym@ugcs.caltech.edu
-
-
-
-
- +++++++++++++++++++++++++++
-
- >From Carl R. Osterwald <carl_osterwald@nrel.gov>
- Date: Fri, 21 Oct 1994 17:23:44 GMT
- Organization: National Renewable Energy Laboratory
-
- In article <387t0n$3rr@gap.cco.caltech.edu> Anthony Molinaro,
- anthonym@puree.ugcs.caltech.edu writes:
- >Now, he tells me he needs a delay time smaller than one tick.
- >I know that the time manager can do this but I have been
- >unable to get it to work. I guess my confusion arises in the
- >type declarations and getting all of the types to match for
- >functions InsXTime(), PrimeTime(), and such. The Inside
-
- Here is an example of a Time Manager task:
-
- typedef struct
- {
- TMTask tm_task;
- long A5;
- } time_info;
-
- Initialization:
- timer_rec.tm_task.tmAddr = (TimerProcPtr)&time_task;
- timer_rec.tm_task.tmWakeUp = 0;
- timer_rec.tm_task.tmReserved = 0;
- timer_rec.A5 = SetCurrentA5();
- InsXTime( (QElemPtr)&timer_rec );
- PrimeTime( (QElemPtr)timer_rec, period ); <<-- This starts the task
-
- static void time_task (void)
- {
- time_info *timer_rec;
- long current_A5;
-
- asm
- {
- MOVE.L A1,timer_rec
- MOVE.L A5,current_A5
- };
- SetA5(timer_rec->A5);
- PrimeTime( (QElemPtr)timer_rec, period ); <<-- This restarts
- the task
- SetA5(current_A5);
- } // time_task
-
- You can access your globals between the SetA5 calls. Because the time
- task runs as an interrupt, it is best to minimize processing inside. In
- your case, I would just set a global flag that is polled in the main
- event loop to see if it is time to turn the device on or off.
-
- +++++++++++++++++++++++++++
-
- >From h+@nada.kth.se (Jon W{tte)
- Date: Fri, 21 Oct 1994 18:48:34 +0100
- Organization: Royal Institute of Something or other
-
- In article <387t0n$3rr@gap.cco.caltech.edu>,
- anthonym@puree.ugcs.caltech.edu (Anthony Molinaro) wrote:
-
- >Now, he tells me he needs a delay time smaller than one tick.
- >I know that the time manager can do this but I have been
- >unable to get it to work. I guess my confusion arises in the
-
-
- All you need is the system call Microseconds. You can write
- your own Delay.
-
- Cheers,
-
- / h+
-
-
- --
- Jon W$E4tte (h+@nada.kth.se), Hagagatan 1, 113 48 Stockholm, Sweden
- Not speaking for the Microsoft Corporation.
-
-
- +++++++++++++++++++++++++++
-
- >From gbolsinga@aol.com (GBolsinga)
- Date: 24 Oct 1994 17:20:05 -0400
- Organization: America Online, Inc. (1-800-827-6364)
-
- In article <387t0n$3rr@gap.cco.caltech.edu>,
- anthonym@puree.ugcs.caltech.edu (Anthony Molinaro) writes:
-
- >pascal void MyTimeTask(void)
- >{ DIG_Out_Line(4, notes[note].portout, notes[note].line, 0);
- >}
-
- Look at the other sample code: it looks good. Another problem might
- be that this function DIG_Out_Line can't move memory.
-
- MyTimeTask executes at interupt time, so just set a global, and in
- your idle in your event loop check for the global changing and then
- call your function.
-
- Greg Bolsinga
- MPI Multimedia
-
-
- +++++++++++++++++++++++++++
-
- >From Tim Dorcey <td11@cornell.edu>
- Date: 25 Oct 1994 19:01:49 GMT
- Organization: Cornell University
-
- In article <AACDBD82966813F759@klkmac005.nada.kth.se> Jon W{tte,
- h+@nada.kth.se writes:
- >All you need is the system call Microseconds. You can write
- >your own Delay.
-
- Do anyone know where the Microseconds call is documented? I stumbled
- upon it in <Timer.h>, but can't find documentation for it anywhere. Is
- it safe to assume that it is available on any system that has the
- "Revised Time Manager?" I had written my own version, using
- InsTime/RmvTime, which seems to work fine, but I'd just as soon use the
- system call if it's equally available.
-
- Tim Dorcey
- Tim_Dorcey@cornell.edu
-
- ---------------------------
-
- >From joey@caseware.com (Joey Caturay)
- Subject: Dynamic Dialogs?
- Date: Thu, 13 Oct 1994 15:15:23 GMT
- Organization: CaseWare
-
- I seem to recall a MacTutor/Tech article about writing dynamic dialogs (i.e.
- dialogs in which controls change based on a selection in the dialog. The
- Metrowerks Project Preference dialog is an example).
-
- Is there source anywhere for dynamic dialogs?
-
- Thanks,
-
- joey
-
- +++++++++++++++++++++++++++
-
- >From johns@efn.org (John Selhorst)
- Date: Fri, 14 Oct 1994 01:07:40 GMT
- Organization: hisself
-
- In article <joey.23.2E9D4F0B@caseware.com>, joey@caseware.com (Joey
- Caturay) wrote:
-
- > I seem to recall a MacTutor/Tech article about writing dynamic dialogs
- (i.e.
- > dialogs in which controls change based on a selection in the dialog. The
- > Metrowerks Project Preference dialog is an example).
- >
- > Is there source anywhere for dynamic dialogs?
- >
- > Thanks,
- >
- > joey
-
- There are some nice snippets with dynamic dialogs on the developer CD and
- probably on ftp.apple.com or whatever it's called now.
-
- Johnny
-
- johns@efn.org
-
- +++++++++++++++++++++++++++
-
- >From gurgle@dnai.com (Pete Gontier)
- Date: Sat, 15 Oct 1994 02:39:20 -0800
- Organization: Integer Poet Software
-
- In article <joey.23.2E9D4F0B@caseware.com>, joey@caseware.com (Joey
- Caturay) wrote:
-
- > I seem to recall a MacTutor/Tech article about writing dynamic dialogs
- (i.e.
- > dialogs in which controls change based on a selection in the dialog. The
- > Metrowerks Project Preference dialog is an example).
- > Is there source anywhere for dynamic dialogs?
-
- Just get creative with HideDItem and ShowDItem. I recently implemented a
- NewsWatcher-style dialog this way (and it was no coincidence...). There's
- a popup menu at the top from which the user can select a set of dialog
- items. The items always exist, but most of them are hidden most of the
- time. Creating this dialog can be a pain unless you have a cool dialog
- editor like the one in Resorcerer which actually lets you show and hide
- ranges of items in the same way the Dialog Manager will do at run-time.
- (It's been
-
- This all said, if you're contemplating doing this, it may also be the case
- that you are running into other limitations of the Dialog Manager.
- Consider using something else, like any one of the several commercial
- view-management systems (off the top of my head, QuickApp, AppsToGo,
- MacApp, TCL, PowerPlant, FaceIt), or roll your own. (It's not all that
- hard if all you want is a list of items like the Dialog Manager tracks.
- Trees get messy, of course.)
-
- --
-
- Pete Gontier // CTO, Integer Poet Software // gurgle@dnai.com
-
- "A Princeton Review executive said the whole affair was not that important
- and offered to relinquish the Kaplan domain name 'for a case of beer'."
- -- Chris Gulker, SF Examiner
-
- +++++++++++++++++++++++++++
-
- >From gurgle@dnai.com
- Date: 14 Oct 94 21:39 GMT+0300
- Organization: (none)
-
- In article <joey.23.2E9D4F0B@caseware.com>, joey@caseware.com (Joey
- Caturay) wrote:
-
- > I seem to recall a MacTutor/Tech article about writing dynamic dialogs
- (i.e.
- > dialogs in which controls change based on a selection in the dialog. The
- > Metrowerks Project Preference dialog is an example).
- > Is there source anywhere for dynamic dialogs?
-
- Just get creative with HideDItem and ShowDItem. I recently implemented a
- NewsWatcher-style dialog this way (and it was no coincidence...). There's
- a popup menu at the top from which the user can select a set of dialog
- items. The items always exist, but most of them are hidden most of the
- time. Creating this dialog can be a pain unless you have a cool dialog
- editor like the one in Resorcerer which actually lets you show and hide
- ranges of items in the same way the Dialog Manager will do at run-time.
- (It's been
-
- This all said, if you're contemplating doing this, it may also be the case
- that you are running into other limitations of the Dialog Manager.
- Consider using something else, like any one of the several commercial
- view-management systems (off the top of my head, QuickApp, AppsToGo,
- MacApp, TCL, PowerPlant, FaceIt), or roll your own. (It's not all that
- hard if all you want is a list of items like the Dialog Manager tracks.
- Trees get messy, of course.)
-
- --
-
- Pete Gontier // CTO, Integer Poet Software // gurgle@dnai.com
-
- "A Princeton Review executive said the whole affair was not that important
- and offered to relinquish the Kaplan domain name 'for a case of beer'."
- -- Chris Gulker, SF Examiner
-
- +++++++++++++++++++++++++++
-
- >From ivan_cavero_belaunde@avid.com (Ivan Cavero Belaunde)
- Date: 18 Oct 1994 15:49:43 GMT
- Organization: Avid Technology, Inc.
-
- In article <gurgle-1510940239200001@dynamic-215.dnai.com>, gurgle@dnai.com
- (Pete Gontier) wrote:
-
- > In article <joey.23.2E9D4F0B@caseware.com>, joey@caseware.com (Joey
- > Caturay) wrote:
- >
- > > I seem to recall a MacTutor/Tech article about writing dynamic dialogs
- (i.e.
- > > dialogs in which controls change based on a selection in the dialog. The
- > > Metrowerks Project Preference dialog is an example).
- > > Is there source anywhere for dynamic dialogs?
- >
- > Just get creative with HideDItem and ShowDItem. I recently implemented a
- > NewsWatcher-style dialog this way (and it was no coincidence...). There's
- > a popup menu at the top from which the user can select a set of dialog
- > items. The items always exist, but most of them are hidden most of the
- > time. Creating this dialog can be a pain unless you have a cool dialog
- > editor like the one in Resorcerer which actually lets you show and hide
- > ranges of items in the same way the Dialog Manager will do at run-time.
- > (It's been
-
- I thought NewsWatcher used AppendDITL, RemoveDITL, etc. I do remember
- John's sample code from disinfectant containing routines along the lines
- of AppendDITL and RemoveDITL to allow you to append and remove items to
- the dialog (the Sys7/CTB routines of the same names work as long as you
- DON'T use 'ictb' resources - otherwise they can crash horribly). I don't
- have any source, but you might also want to look at either the QuickTime
- Sequence Grabber Panel Component API or the Sound Control Panel Component
- API for some pointers and ideas - it defines a clean layer between a main
- piece of code that you write that controls the main dialog (ie the NW
- popup menu or the "scrolling icon item" list in CW) and "plug-in"
- subcomponents that control the independent panels.
-
- -Ivan
- - --
- Ivan Cavero Belaunde (ivan_cavero_belaunde@avid.com)
- Avid VideoShop Lead
- Avid Technology, Inc.
- Disclaimer: All views expressed are entirely my own and do not
- reflect the opinions of Avid Technology, Inc.
-
- +++++++++++++++++++++++++++
-
- >From reed@medicine.wustl.edu (Thomas Reed)
- Date: Tue, 18 Oct 1994 11:21:13 -0500
- Organization: Washington University
-
- In article <gurgle-1510940239200001@dynamic-215.dnai.com>, gurgle@dnai.com
- (Pete Gontier) wrote:
-
- >In article <joey.23.2E9D4F0B@caseware.com>, joey@caseware.com (Joey
- >Caturay) wrote:
- >
- >> I seem to recall a MacTutor/Tech article about writing dynamic dialogs
- >
- >Just get creative with HideDItem and ShowDItem.
-
- The method I like better is to set up your dialog with a "base" DITL,
- containing whatever controls are going to be static for all settings.
- This might contain your OK and Cancel buttons and a pop-up, if that's the
- method you want to use to switch to a different set of controls. Then,
- you define a separate DITL for each setting (say you have an options
- dialog with three different options topics selectable on a pop-up menu,
- you use 3 different DITLs, one for each topic). Make sure that the new
- DITL can be overlayed on the "base" DITL the way you want it. I believe
- that you may also want to specify that the "base" DLOG is not initially
- visible.
-
- Then, in your program, you use AppendDITL to overlay the DITLs. Just open
- your base DLOG, then call AppendDITL to overlay the current setting on the
- base DITL. The item numbers for the one you're adding will be bumped up
- by the number of items in your base DITL.
-
- Then, when the user switches to a different set of controls, you use
- ShortenDITL to remove the old controls and AppendDITL to add the new set.
-
- You've of course also got to take into account which set of controls
- you're using in your dialog handling routines, as item #5 under one
- setting may not be the same as item #5 under another. However, this is
- not too hard to do.
-
- I believe that this is the way that NewsWatcher does things.
-
- -Thomas
-
- =====================================================
- Thomas Reed Washington University
- reed@telesphere.wustl.edu Medical School
- reed@medicine.wustl.edu Saint Louis, MO
- - ---------------------------------------------------
- Clothes make the man. Naked people have little or no
- influence on society. -- Mark Twain
- =====================================================
-
- Opinions posted are not the opinions of Wash. U.
-
- +++++++++++++++++++++++++++
-
- >From bb@lightside.com (Bob Bradley)
- Date: Mon, 17 Oct 1994 03:22:02 -0800
- Organization: SS Software Inc.
-
- In article <ivan_cavero_belaunde-1810941144230001@predator.avid.com>,
- ivan_cavero_belaunde@avid.com (Ivan Cavero Belaunde) wrote:
-
- > I thought NewsWatcher used AppendDITL, RemoveDITL, etc. I do remember
- > John's sample code from disinfectant containing routines along the lines
- > of AppendDITL and RemoveDITL to allow you to append and remove items to
- > the dialog (the Sys7/CTB routines of the same names work as long as you
- > DON'T use 'ictb' resources - otherwise they can crash horribly).
-
- Any dialog with an ictb resource can't use AppendDITL/ShortenDITL? Is
- there any other way to get the functionality of those two routines when
- using dialogs with ictb resources without modifying the DITL in memory
- directly?
-
- I had a lot problems in the past with AppendDITL and ShortenDITL and could
- never figure it out until you mentioned they didn't work with ictb
- resources. I end up using the Show/Hide method but, when working with
- dialogs with a lot of items, it gets difficult.
-
- +++++++++++++++++++++++++++
-
- >From rmah@panix.com (Robert Mah)
- Date: Tue, 18 Oct 1994 18:15:26 -0500
- Organization: One Step Beyond
-
- Jason_Titus@odsnet.com wrote:
-
- ) I have been trying to work out a solution to a problem where I have a
- ) base window and can have a thousand or so possible midifications. It
- ) sounds like having these numerous DITL's and appending them would be
- ) the best solutions,but -
- )
- ) how do I create DITLs? I can't find real descriptions of their format..
- ) My goal is to be able to create DITLs from text files of information
- ) (ie - a text file made up of checkbox titles) so I can easily create
- ) thousands of windows.
-
- The usual way is to use ResEdit's or Resorcerer's graphical editors.
-
- However given that you want to parse a text file to create user interfaces,
- and assuming that the text file is not in rez format, I think you're going
- to have to write a parser and create windows on the fly. That is, don't
- use DITL and DLOG resources, but instead operate directly at the Window
- Manager, Control Manager, List Manager and TextEdit levels.
-
- Depending upon the complexity of your "interface description language",
- this might not be too hard or it might be a royal pain in the...
-
- Cheers,
- Rob
- _____________________________________________________________________
- Robert S. Mah Software Development +1.212.947.6507
- One Step Beyond and Network Consulting rmah@panix.com
-
- +++++++++++++++++++++++++++
-
- >From leonardr@netcom.com (Leonard Rosenthol)
- Date: Wed, 19 Oct 1994 21:47:29 GMT
- Organization: Aladdin Systems, Inc.
-
- In article <bb-1710940322020001@user31.lightside.com>, bb@lightside.com
- (Bob Bradley) wrote:
-
- > In article <ivan_cavero_belaunde-1810941144230001@predator.avid.com>,
- > ivan_cavero_belaunde@avid.com (Ivan Cavero Belaunde) wrote:
- >
- > > I thought NewsWatcher used AppendDITL, RemoveDITL, etc. I do remember
- > > John's sample code from disinfectant containing routines along the lines
- > > of AppendDITL and RemoveDITL to allow you to append and remove items to
- > > the dialog (the Sys7/CTB routines of the same names work as long as you
- > > DON'T use 'ictb' resources - otherwise they can crash horribly).
- >
- > Any dialog with an ictb resource can't use AppendDITL/ShortenDITL? Is
- > there any other way to get the functionality of those two routines when
- > using dialogs with ictb resources without modifying the DITL in memory
- > directly?
- >
- That info about 'ictb's is NOT true. The System routines AppendDITL
- and ShortenDITL will work just fine with ictb's GIVEN THE LIMITATIONS of
- ictb resources (like they suck big time!).
-
-
- Leonard
- - ------------------------------------------------------------------------
- Leonard Rosenthol Internet: leonardr@netcom.com
- Director of Advanced Technology AppleLink: MACgician
- Aladdin Systems, Inc. GEnie: MACgician
-
- +++++++++++++++++++++++++++
-
- >From ivan_cavero_belaunde@avid.com (Ivan Cavero Belaunde)
- Date: 21 Oct 1994 14:44:58 GMT
- Organization: Avid Technology, Inc.
-
- In article <bb-1710940322020001@user31.lightside.com>, bb@lightside.com
- (Bob Bradley) wrote:
- > In article <ivan_cavero_belaunde-1810941144230001@predator.avid.com>,
- > ivan_cavero_belaunde@avid.com (Ivan Cavero Belaunde) wrote:
- > > I thought NewsWatcher used AppendDITL, RemoveDITL, etc. I do remember
- > > John's sample code from disinfectant containing routines along the lines
- > > of AppendDITL and RemoveDITL to allow you to append and remove items to
- > > the dialog (the Sys7/CTB routines of the same names work as long as you
- > > DON'T use 'ictb' resources - otherwise they can crash horribly).
- >
- > Any dialog with an ictb resource can't use AppendDITL/ShortenDITL? Is
- > there any other way to get the functionality of those two routines when
- > using dialogs with ictb resources without modifying the DITL in memory
- > directly?
- >
- > I had a lot problems in the past with AppendDITL and ShortenDITL and could
- > never figure it out until you mentioned they didn't work with ictb
- > resources. I end up using the Show/Hide method but, when working with
- > dialogs with a lot of items, it gets difficult.
-
- Yeah, I had a lot of problems with those as well. Some of the problems
- (text items changing colors, for example) hinted at a confused 'ictb', so
- I stopped using one and everything was fine (it meant I had to use
- useritems for some stuff, though). This suspicion was confirmed by someone
- on the net who had worked on the AppendDITL/ShortenDITL code for Apple -
- 'ictb's are not supported by those calls.
-
- Upon rereading my post above, I realize I imply John Norstad's
- DITL-manipulation code supports 'ictb'. I actually don't know whether
- that's the case or not - but it'd be easy to check if you need that
- functionality.
-
- -Ivan
- - --
- Ivan Cavero Belaunde (ivan_cavero_belaunde@avid.com)
- Avid VideoShop Lead
- Avid Technology, Inc.
- Disclaimer: All views expressed are entirely my own and do not
- reflect the opinions of Avid Technology, Inc.
-
- +++++++++++++++++++++++++++
-
- >From Peter_Gontier@novell.com (Pete Gontier)
- Date: Mon, 24 Oct 1994 20:05:03 -0800
- Organization: Novell, Inc., Walnut Creek Macintosh Site
-
- In article <ivan_cavero_belaunde-1810941144230001@predator.avid.com>,
- ivan_cavero_belaunde@avid.com (Ivan Cavero Belaunde) wrote:
-
- > In article <gurgle-1510940239200001@dynamic-215.dnai.com>, gurgle@dnai.com
- > (Pete Gontier) wrote:
- >
- > > Just get creative with HideDItem and ShowDItem. I recently implemented a
- > > NewsWatcher-style dialog this way...
- >
- > I thought NewsWatcher used AppendDITL, RemoveDITL, etc...
-
- I don't know for sure what NewsWatcher uses, but what I remember of the
- way he stored his DITLs supports the notion that he's using AppendDITL,
- etc.
-
- When I said "NewsWatcher-style" I only meant the user interface is similar.
-
- --
- Views expressed here do not necessarily reflect the views of Novell.
-
- +++++++++++++++++++++++++++
-
- >From ivan_cavero_belaunde@avid.com (Ivan Cavero Belaunde)
- Date: 31 Oct 1994 19:43:51 GMT
- Organization: Avid Technology, Inc.
-
- In article <leonardr-1910941347290001@leonardr.slip.netcom.com>,
- leonardr@netcom.com (Leonard Rosenthol) wrote:
-
- > In article <bb-1710940322020001@user31.lightside.com>, bb@lightside.com
- > (Bob Bradley) wrote:
- >
- > > In article <ivan_cavero_belaunde-1810941144230001@predator.avid.com>,
- > > ivan_cavero_belaunde@avid.com (Ivan Cavero Belaunde) wrote:
- > >
- > > > I thought NewsWatcher used AppendDITL, RemoveDITL, etc. I do remember
- > > > John's sample code from disinfectant containing routines along the
- lines
- > > > of AppendDITL and RemoveDITL to allow you to append and remove items to
- > > > the dialog (the Sys7/CTB routines of the same names work as long as you
- > > > DON'T use 'ictb' resources - otherwise they can crash horribly).
- > >
- > > Any dialog with an ictb resource can't use AppendDITL/ShortenDITL? Is
- > > there any other way to get the functionality of those two routines when
- > > using dialogs with ictb resources without modifying the DITL in memory
- > > directly?
- > That info about 'ictb's is NOT true. The System routines AppendDITL
- > and ShortenDITL will work just fine with ictb's GIVEN THE LIMITATIONS of
- > ictb resources (like they suck big time!).
-
- Are you sure? I had an exchange on the net about a year/year and a half
- ago with someone (his name slips me) that had worked on the
- Append/RemoveDITL routines at Apple, and he explicitly mentioned that they
- didn't support 'ictb's. This was at the time when I was having problems
- with them: I kept getting items coming up in funny colors and fonts when I
- appended them, as well as stray crashes inside UpdateDialog. Nuking the
- 'ictb's got rid of all those problems.
-
- On a related note, how do they suck big time? My only beef is that they
- are hard to edit unless you have Resorcerer, which is another one of the
- bazillion reasons to get Resorcerer and skip ResEdit...
-
- -Ivan
- - --
- Ivan Cavero Belaunde (ivan_cavero_belaunde@avid.com)
- Avid VideoShop Lead
- Avid Technology, Inc.
- Disclaimer: All views expressed are entirely my own and do not
- reflect the opinions of Avid Technology, Inc.
-
- ---------------------------
-
- >From hsieh@netcom.com (Julia Hsieh)
- Subject: How to install your own templates using Macsbug 6.5d6???
- Date: Mon, 31 Oct 1994 17:25:57 GMT
- Organization: NETCOM On-line Communication Services (408 261-4700 guest)
-
-
- i've just started playing with custom templates in Macsbug, but since
- the new version doesn't have a separate Debugger Prefs file with the
- resources in it, how do i add my own custom templates?
-
- also, i'm confused from one of the recent threads, is the Debugger
- Prefs a file or a folder.
-
- thanks.
- -julia
-
- --
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
- If each day falls
- inside each night,
- there exists a well
- where clarity is imprisoned.
-
- We need to sit on the rim
- of the well of darkness
- and fish for fallen light
- with patience.
-
- -Pablo Neruda
- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-
-
- +++++++++++++++++++++++++++
-
- >From johns@efn.org (John Selhorst)
- Date: Tue, 1 Nov 1994 14:29:33 GMT
- Organization: hisself
-
- In article <hsiehCyJsFA.7vH@netcom.com>, hsieh@netcom.com (Julia Hsieh)
- wrote:
-
- > i've just started playing with custom templates in Macsbug, but since
- > the new version doesn't have a separate Debugger Prefs file with the
- > resources in it, how do i add my own custom templates?
- >
- > also, i'm confused from one of the recent threads, is the Debugger
- > Prefs a file or a folder.
- >
- > thanks.
- > -julia
- >
-
- You've almost answered your own question. Yes, Debugger Prefs is a file
- that goes into the system folder. It still works with MacsBug 6.5. If
- you don't have one, make one yourself. You can make one with ResEdit.
-
- Johnny
-
- johns@efn.org
-
- +++++++++++++++++++++++++++
-
- >From jonasw@lysator.liu.se (Jonas Wallden)
- Date: 1 Nov 1994 16:50:44 GMT
- Organization: (none)
-
- hsieh@netcom.com (Julia Hsieh) writes:
-
- >i've just started playing with custom templates in Macsbug, but since
- >the new version doesn't have a separate Debugger Prefs file with the
- >resources in it, how do i add my own custom templates?
-
- I'm running 6.5d6 and it uses a Debugger Prefs file.
-
- You can also drop your templates and macros into the MacsBug file itself.
- Just open it in ResEdit and paste them.
-
- >also, i'm confused from one of the recent threads, is the Debugger
- >Prefs a file or a folder.
-
- It's a resource file, and should be located at the top level of your
- System Folder.
-
- >thanks.
- >-julia
-
- BTW, welcome on board! You just doubled the female/male ratio of Mac hackers
- posting in this newsgroup... :-)
- ............... ....................... ........... ...............
- jonas wallden internet applelink phone/fax
- mac hacker jonasw@lysator.liu.se sw1369 +46-13-176084
-
- +++++++++++++++++++++++++++
-
- >From devon_hubbard@taligent.com (Devon Hubbard)
- Date: Mon, 31 Oct 1994 18:57:56 GMT
- Organization: Taligent, Inc.
-
- In article <hsiehCyJsFA.7vH@netcom.com>, hsieh@netcom.com (Julia Hsieh)
- wrote:
-
- >i've just started playing with custom templates in Macsbug, but since
- >the new version doesn't have a separate Debugger Prefs file with the
- >resources in it, how do i add my own custom templates?
-
- Since most of the dcmds/templates in the old 'Debugger Prefs' were always
- shipped with Macsbug, someone got smart at Apple (you know who you are :-)
- and just put that stuff in Macsbug itself and then there was no need for
- the separate prefs file. This didn't eliminate the usage of that prefs
- file though. So if you want to add your own templates, macros, etc. go
- right ahead and create a file called 'Debugger Prefs' and put your stuff
- in there. The file type/creator is usually 'rsrc'/'RSED' but it really
- doesn't matter to Macsbug as it'll open the rsrc fork of any type file
- called 'Debugger Prefs'.
-
- Also note that because Apple ships Macsbug this way, there is no need to
- merge their prefs with yours when a new release comes out.
-
- dEVoN
-
- - -----------------------------------------------------------------------
- Devon Hubbard Silicon Pilot
- devon_hubbard@taligent.com Taligent, Inc
- - -----------------------------------------------------------------------
- "No amount of genius can overcome a preoccupation with detail." -Einstein
-
- ---------------------------
-
- >From schultz@iastate.edu (Jonathan Schultz)
- Subject: IM: Networking book question
- Date: 28 Oct 94 07:08:51 GMT
- Organization: Iowa State University, Ames, Iowa
-
- Does IM: Networking totally supercede Inside AppleTalk?
-
- Jonathan
- schultz@iastate.edu
-
- --
- - -----------------
- Jonathan Schultz
- schultz@iastate.edu
-
- +++++++++++++++++++++++++++
-
- >From jumplong@aol.com (Jump Long)
- Date: 29 Oct 1994 21:32:03 -0400
- Organization: America Online, Inc. (1-800-827-6364)
-
- In article <schultz.783328131@pv3449.vincent.iastate.edu>,
- schultz@iastate.edu (Jonathan Schultz) writes:
-
- >Does IM: Networking totally supercede Inside AppleTalk?
-
- No it doesn't.
-
- IM: Networking replaces the AppleTalk chapters of Inside Macintosh volumes
- II, IV, V, and VI (the old Inside Macintosh volumes). IM: Networking
- describes the Macintosh AppleTalk API. Inside AppleTalk describes the
- AppleTalk *protocols* - not the API for any particular implementation of
- AppleTalk.
-
- While Inside AppleTalk isn't required to use most parts of the Macintosh
- AppleTalk API, it is useful when debugging AppleTalk problems you may have
- when using the Macintosh API because it describes the network packets and
- describes how the protocol was designed to be used. To use some parts of
- the Macintosh API, you must have Inside AppleTalk because the Macintosh
- API doesn't build the request packets or disassemble the reply packets for
- you. An example of that is using the .XPP driver to send AFP requests.
- Since the system doesn't build those packets for you, you'll have to use
- the information in Inside AppleTalk to know how to build them yourself.
-
- - Jim Luther
-
- ---------------------------
-
- >From Jaeger@fquest.com (Brian Stern)
- Subject: INIT Writing FAQ [1-3]
- Date: 28 Oct 1994 00:37:24 GMT
- Organization: The University of Texas at Austin, Austin, Texas
-
- Answers to Frequently Asked Questions about writing System Extensions
- on the Macintosh Computer. Version 1.0 10/94
-
- This document is Copyright (c) 1994 by Brian Stern.
- I can be contacted by email at <Jaeger@fquest.com> on Internet.
-
- The purpose of this FAQ list is to provide information on the writing
- of system extensions. This arcane art is difficult to learn and the
- existing information on the subject is spread around in various
- places. Hopefully the information here will help new and old INIT
- writers to write better INITs in less time.
-
- The questions in this document are broken into two sections: System
- Extensions and Trap Patches. While most extensions contain trap
- patches these subjects seemed different so I have separated them.
-
- FAQ lists like this one are an integral part of Usenet. When I
- started reading Usenet news I assure you that I knew nothing about
- writing extensions. I learned by posting questions to
- comp.sys.mac.programmer and by reading other's questions and
- responses. Let me take this space to give you a few tips on phrasing
- of questions to newsgroups.
-
- When asking a question try to make the title as descriptive as
- possible. Most people don't have time to read every question posted
- and will ignore posts whose titles are unclear or meaningless. Don't
- post questions titled 'HELP, My program doesn't work', or worse
- 'URGENT NEED HELP with program'. I'm sure it's urgent to you, but
- not to me. Always indicate that you're asking a questing by
- including a (you guessed it) question mark. Consider these titles:
- 'Programmers make big salaries' and 'Programmers make big salaries?'
- Don't waste people's time with the former when you mean the latter.
- Another way to indicate a question is like this: '[Q] Programmers
- make big salaries?'. Try to include one of the words 'who, what,
- when, where, why, or how' in the titles of your questions. Your
- questions are much more likely to be answered by someone who actually
- knows the answer if your title is clear.
-
- The code samples in this document were developed with Think C. You
- may need to make some changes to use them with other development
- systems. I've used inline assembly in many of the code samples. To
- my eye this makes things more clear since it's obvious what's going
- on. Not everyone agrees with this and not all development
- environments provide inline assembly. It's possible to rewrite most
- or all of this code by use of inline functions. If you're writing in
- Pascal or using CodeWarrior you'll have to do it that way.
-
- You'll be able to find information on general questions of Mac
- programming in the FAQ list maintained by Jon Watte at:
- ftp://nada.kth.se/pub/hacks/mac-faq/CSMP_PD_FAQ
-
- If you have questions about writing extensions that aren't addressed
- in this document or any comments about it feel free to send them to
- me. If I know the answer or can find it out it may find its way into
- a later version.
-
- This document may be distributed freely as long as no changes are
- made to it. It may not be distributed in ways in which the user must
- pay for the document, other than reasonable download costs or costs
- for the medium, without the consent of the author.
-
- Thanks to the following people who provided sample code and made
- constructive comments: Pete Gontier, Dair Grant, Chelly Green, Devon
- Hubbard, Peter Lewis, Jim Walker, Jim Wintermyre.
-
- - -------------------------------------------------------------------
- System Extension Writing FAQ Outline:
-
- System Extensions:
-
- [1] What is an INIT, exactly?
- [2] Should I write an INIT?
- [3] Can I write an INIT that makes the application menu into a
- hierarchical menu?
- [4] Do I need to know assembler to write an INIT?
- [5] Can you show me a sample INIT?
- [6] Can I have global variables in my INIT?
- [7] How do I debug an INIT?
- [8] How do I write a Control Panel-INIT combination?
- [9] How do I capture keystrokes?
- [10] How can my extension get time periodically?
- [11] How should an INIT manage memory?
- [12] How do I get my INIT to turn itself off?
- [13] How do I get my INIT to show its icon like all the other cool
- INITs do?
- [14] How do I show a dialog from my INIT?
- [15] How do I maintain compatibility with future systems?
- [16] Any tips for INIT writing?
-
- Trap Patches:
-
- [17] What exactly is a trap patch?
- [18] What's the difference between a head patch and a tail patch?
- [19] How do I patch a trap?
- [20] How do I patch a register-based trap?
- [21] Can you show me an example tail patch?
- [22] How do I patch a selector-based trap?
- [23] How do I patch a trap on the PPC?
- [24] Can I write a fat trap?
- [25] Tips?
- [26] What other sources of information are available?
-
- - -------------------------------------------------------------------
-
- [1] What is an INIT, exactly?
-
- An INIT is a type of code resource that is loaded into memory and
- executed during the startup process. They're called INITs because
- they're resources of type 'INIT'. INITs load at the end of the
- startup process, after the hardware checks have been done and the
- system has been started. The span of time during which INITs load
- and execute is known as INIT time. Applications don't load until
- after INIT time and in most cases the first application to load is
- the Finder.
-
- Because they load before all applications, INITs can modify the
- system in a way that affects all applications. They can add new
- functionalities and modify the way in which many processes occur on
- the Mac. Apple often supplies new additions and updates to system
- software as INITs. This includes things such as the Drag-and-Drop
- Manager, Thread Manager, Speech Manager, and Sound Manager 3.0. At
- some point these new features are rolled into a new software release
- and eventually they are included in new ROMs, but they all start life
- as INITs.
-
- Apple recommends that the term 'system extension' be used when
- communicating with non-programmers. This name carries the
- implication that they extend the functionality of the system. You'll
- see the terms 'INIT', 'extension', and 'system extension' used to
- mean the same thing throughout this document.
-
- Extensions are loaded in a defined order. Resources of type 'INIT'
- can be found in files of type 'INIT' (System Extension), 'cdev'
- (Control Panel), 'RDEV' (Chooser Device), 'appe' (application
- extension), and 'scri' (script system extensions). In order to be
- loaded, the INIT resource must be in one of these file types in one
- of several locations in the System Folder.
-
- Under system 7 INITs are loaded first from the Extensions Folder in
- alphabetical order. INITs present in script system extension files
- (filetype 'scri') load before INITs present in system extension files
- (filetype 'INIT'). Next, any INITs in the Control Panels folder are
- loaded in alphabetical order. Any INITs present at the root level of
- the System Folder are loaded after that. This order of loading is
- important if an extension is dependent on the presence of another
- extension. For example, if an INIT resource in an INIT file named
- 'SpeakAll' is dependent on the presence of the 'Speech Manager'
- extension, it either needs to have its name changed to something that
- sorts after 'Speech Manager' or it has to be located in the Control
- Panels folder, since extensions in the Control Panels folder load
- after extensions in the Extensions Folder.
-
- In system 6 the Extensions Folder and Control Panels Folders don't
- exist. Extensions are simply loaded in alphabetical order from the
- root level of the System Folder.
-
- --
- [2] Should I write an INIT?
-
- System extensions are not easy to write. If this is your first
- attempt at Mac programming, the answer to this question is NO. Many
- experienced Mac programmers have never written one and don't intend
- to.
-
- There are a number of other ways to add functionality without writing
- an extension. If you want to add functionality to a single
- application then think about writing an FKEY. These are invoked by
- hitting cmd-shift-number and perform an action at that time only.
- The standard screen shot (cmd-shift-3) is one example.
-
- Another user-invokable means of adding functionality is plug-in
- modules. A number of commercial software packages support plug-ins
- that can add functionality in a straightforward manner. This
- includes PhotoShop, Quark Express, Hypercard and others.
-
- Another means of adding functionality is the use of a background-only
- application, AKA faceless-background application (fba). Fbas are
- applications without a user interface. One type of fba is known as
- an application extension. These are applications whose resource
- files are of type 'appe'. They are placed in the extensions folder
- (or the Startup Items Folder) and are started up after INIT time.
- They can communicate with other processes by Apple Events and by
- Gestalt selectors. If you don't need to patch a trap then an fba may
- be the way to add functionality to the system. Since an fba runs as
- a normal process there are some things that it can do that system
- extensions cannot do (or at least cannot do safely), like launch
- applications and send and receive Apple Events. An INIT resource in
- the resource fork of an application extension in the Extensions
- Folder will load normally at INIT time. See issue 9 of develop and
- the Tech Note PS 2 - Background-Only Applications for more info.
-
- Also consider an application that is started up by being placed in
- the startup items folder. The Screen Saver 'Dark Side of the Mac' is
- written in this way. Screen Savers are traditionally written as
- extensions because extensions can have access to the mouse location
- and all keyboard events. However an intelligently written
- application can do the same and be more compatible.
-
- If none of these things seems like it will work for you and you are
- thinking something like 'I want X to happen every time a resource is
- loaded', or otherwise add to or replace the system's functionality in
- some way then an extension is probably what you need.
-
- Remember that when developing system extensions you will be working
- without a net.
-
- --
- [3] Can I write an INIT that makes the application menu into a
- hierarchical menu?
-
- Every couple of weeks someone posts a message on
- comp.sys.mac.programmer entitled 'Neat idea for an init'. These
- posts go on to describe some non-programmer's idea of a great INIT.
- Invariably these posts fall into two groups: those that have already
- been done, and those that should never be done. Think long and hard
- about the design of an extension before starting to write it.
- Consider your target audience. If it's only yourself then you can do
- what you want. My first couple of extensions were just tests to see
- if I could actually do it. The answer to the above question is:
- Maybe you can but probably you shouldn't.
-
- --
- [4] Do I need to know assembler to write an extension?
-
- Yes. Strictly speaking, the simplest extension that just beeps at
- startup and doesn't hang around past INIT time requires no assembler.
- However, any extension that does anything useful will require some
- assembler in order to patch a trap or install a jGNEFilter. The
- extension can be written mostly in a high level language like C or
- Pascal, but there will be bits and pieces that need to be written in
- assembler to keep the stack happy or to access parameters passed in
- registers. Hopefully there will be enough sample code in this
- document to get you on your way if your assembler is weak.
-
- You will often need to inspect the disassembled source of your
- extension. If your development environment doesn't allow this the
- ResEdit Code Viewer will also allow you to inspect code resources.
- It can be found at ftp://ftp.apple.com/dts/mac/tools/resedit/resedit-
- extensions.hqx.
-
- --
- [5] Can you show me a sample INIT?
-
- Here's the code for the 'Hello World' of INITs.
-
- void main(void)
- {
- SysBeep( 5 );
- }
-
- Not very complicated is it? There are a number of additional things
- that are required to make this work:
-
- 1) Set the project type to code resource.
- 2) Set the resource type to 'INIT'.
- 3) Set the resource ID to something (>= 128), and set the resource
- name if desired.
- 4) Set the resource attributes to 'System Heap'.
- 5) Set the resource attributes to 'Locked'.
- 6) Set the filetype of the built code resource file to 'INIT' with
- any creator signature.
- 7) Set the filename of the built code resource file to 'Hello World'.
-
- Let me explain what each of these things does.
-
- 1) Because you're building a standalone code resource your compiler
- needs to know this. This is how the compiler knows to use A4
- addressing, rather than the A5 addressing used in applications.
-
- 2) As mentioned above, extensions are code resources of type 'INIT'.
-
- 3) Like any other resources they have IDs and can have names.
-
- 4) Setting the system heap flag places the code resource in the
- system heap. While not strictly required for this sample, in most
- other extensions we will want the code resource to remain in the
- system heap so this flag must be set. During the process that loads
- and executes INITs a small heap is created. Any memory allocation
- done by the INIT will, by default occur in this heap. Also any
- resources read into memory will, by default, go into this heap. If
- the system heap flag isn't set for the INIT itself then the INIT will
- be loaded into this temporary heap. When the INIT exits the heap is
- disposed and anything in it is lost. If an INIT intends to stay
- around past INIT time then it must have the system heap flag set.
-
- 5) The code resource should never move in memory so the Locked bit
- is set. When a resource with the Locked bit is loaded into memory it
- is loaded as low in the heap as possible. This is what we want since
- the INIT resource will never be unlocked. It is poor design to not
- set the Locked bit and to rely on the INIT to lock itself. In that
- case the INIT will not be loaded low in the system heap. This isn't
- fatal but will lead to fragmentation of the system heap.
-
- Some INITs try to use MoveHHi/HLock to move themselves or associated
- resources high in the system heap. MoveHHi is disabled for the
- system heap. Since the system heap is dynamically sizable the
- concept of the top of the heap is invalid. For this reason MoveHHi
- does nothing when the handle being referred to is within the system
- heap.
-
- 6) The filetype of 'INIT' gives you the generic extension icon, and
- of course allows the extension to load and execute at INIT time.
-
- 7) Set the file name to something like 'Hello World'.
-
- Once these things have been done you can build the code resource and
- drag its file to the System Folder. The Finder should place it in
- the Extensions Folder for you and it should have the generic
- extension icon. When you restart you will hear the beep when the
- extension is loaded.
-
- Every extension must have a routine called 'main'. When the INIT
- resource is loaded into memory during INIT time the system jumps to
- the beginning of the code resource. The header of the code resource
- will normally contain a branch instruction that branches to the main
- routine. This routine does whatever it needs to do and then returns.
- In this 'Hello World' extension all that the main routine does is
- call SysBeep. In more substantial extensions the main routine will
- do things like patch traps, install gestalt selectors, and load
- resources into memory.
-
- --
- [6] Can I have global variables in my INIT?
-
- Yes you can. The Think environment and the CodeWarrior environment
- use A4-based addressing for global variables in code resources. The
- base address of the extension is found in register A0 on entry to the
- extension, and routines are provided to save this value and to set up
- and restore register A4 when the INIT is entered later. (In fact the
- standard header installed by Think C in code resources loads the
- address of the code resource into A0 by use of pc-relative
- addressing.) See the A4-Addressing section of your development
- environment's manual for more information.
-
- When writing extensions with the MPW compilers you may need to use an
- A5-based method for accessing global variables. See the Apple tech
- note 'StandAlone Code, ad nauseam' (#256) for more information on
- this method. ftp://ftp.apple.com/dts/mac/tn/platforms.tools.pt/pt-
- 35-stand-alone-code.hqx
-
- and
-
- "Another take on Globals in Standalone Code", Keith Rollin
- ftp://ftp.apple.com/dts/mac/docs/develop/develop.12.code/globals-in-
- standalone-code.hqx
-
- Here is some sample code using the Think C routines to illustrate
- this:
-
- /****Main*****************************************************/
- void
- main(void) //Main entry point of the extension
- {
- void *pToMe;
- Boolean initedOK;
-
- pToMe = GetA0(); //Save our address locally
-
- RememberA0(); //Save our base address
- SetUpA4(); //Set up A4-based addressing
-
- initedOK = InitAll(); //Patch traps etc.
- if ( initedOK )
- {
- //Make sure we stay around
- DetachResource( RecoverHandle( pToMe) );
- }
-
- RestoreA4(); //Reset A4 to its value on entry
- }
-
- This code sample also illustrates one method extensions can use to
- remain in memory after INIT time. Since extensions are code
- resources they will be removed from memory when their resource files
- are closed. This happens when the main routine exits. To avoid
- this, DetachResource must be called with the handle to the code
- resource. One common mistake with this is not having the code
- resource marked system heap. If it's not marked system heap it will
- be lost when the temporary heap is destroyed, whether it was detached
- or not. The GetA0 routine used above is defined in the tips section
- farther down in this document. Here are a few other methods for an
- extension to detach itself:
-
- void
- main(void) //Another method
- {
- asm
- {
- RecoverHandle //A0 already holdss our address
- move.L A0, -(A7) //DetachResource is stack-based
- DetachResource //so push A0 onto the stack
- }
- }
-
- void
- main(void) //This method uses no assembler
- {
- DetachResource( Get1Resource( 'INIT', kOurResID ) );
- }
-
- --
- [7] How do I debug an INIT?
-
- Debugging is generally the most time consuming, difficult, and all-
- around pain-in-the-neck part of producing good code. That goes
- double for INITs. Unfortunately many parts of INITs must be debugged
- with low level debuggers. The low level debuggers that I know about
- are MacsBug, TMON, and Jasik's Debugger. MacsBug is free and is
- available at ftp://ftp.apple.com/dts/mac/tools/macsbug/macsbug-6-
- 5d6.hqx. The two other low level debuggers are commercialware.
- Jasik's debugger has the ability to do source level debugging of code
- resources, like system extensions.
-
- In most cases, your low level debugger of choice will load before
- INIT time so it can be used to debug initialization of INITs. One
- exception to this is Jasik's Debugger, which loads in two parts. One
- of these is an extension that must load before your extension.
-
- The debugger can be invoked by calling the Debugger() or DebugStr()
- traps. Placing these trap calls in your code will drop you into the
- low level debugger so that you can step through your code and inspect
- registers or memory as needed.
-
- One useful technique is to take advantage of Macsbug's ability to
- process commands after a semicolon in a DebugStr call. The following
- function can display information that you would otherwise have to
- hunt down using hex offsets:
-
- pascal void SomeFunction (arguments)
- {
- // ...
-
- asm { MOVE.L fooP, A0 } // fooP can be any type
- asm { MOVE.L sizeof(*fooP), D0 }
- DebugStr ("\p ; dm rA0 rD0"); // dump (*fooP) in hex
-
- // ...
- }
-
- If you haven't placed Debugger() calls in your code then you will
- have to set a breakpoint in order to step through any trap patches or
- other parts of your extension. Here are a couple of methods to do
- that. If you have patched a trap, say GetResource, if you drop into
- MacsBug and type 'il GetResource' MacsBug will begin to disassemble
- at your patch. You can then set a breakpoint by typing 'br
- GetResource' or br theaddress' where theaddress is the address in hex
- of your patch or some part of it. Type 'brc' when you want to clear
- all breakpoints. Using the A-trap commands will also work. 'atb
- GetResource' will set a break and 'atc' will clear all A-trap
- breakpoints.
-
- If you want to set a breakpoint in some other part of your extension,
- say in a jGNEFilter, then you need another way of finding its
- location in memory. In MacsBug type 'hx syszone^' or just 'hx' to
- set the current heap to the system heap (where your extension is
- located). Type 'br ' (don't hit return yet) and then type cmd-D to
- view the names of all the routines in the system heap that were
- compiled with MacsBug names turned on (like yours, right?) Scroll
- down until you find the name of your routine. Hit enter and the
- command line should look like 'br yourRoutineName'. Hit enter again
- and the breakpoint will be set. You can also simply type 'br
- yourRoutineName' and MacsBug will find it for you. The zone must be
- set to the zone containing the routine that you want to break on for
- MacsBug to find it, so make sure to set the zone to the system zone.
-
- Identifying your extension in the system heap is dependent on
- compiling it with the MacsBug symbols option turned on. This inserts
- Ascii versions of the names of each function in the compiled code in
- such a way the MacsBug , and other debuggers can find these names.
- Jasik's debugger uses a different method for identifying your code
- that is based on SYM files, which are generated by your compiler.
- The SYM files allows Jasik's debugger to do source level debugging of
- INITs and other code resources.
-
- I have used a two-project method, when developing INITs and other
- code resources, that helps to cut down debugging time. Any extension
- consists of essentially two parts: the initialization portion and the
- implementation portion. The initialization portion detaches the
- resource as described above, shows the icon, and often patches traps.
- The implementation portion contains the actual trap patches. It is
- quite possible, and desirable, to test the implementation portion in
- the context of an application, rather than as an INIT. To accomplish
- this your project consists of three parts, which for a simple case
- would be three files.
-
- TesterApp Project:
- SetUpApplication.c Simple application shell that sets up
- the trap patches and provides a
- mechanism to call the traps
- TrapPatches.c Code for the trap patches
-
- INIT Project:
- SetUpINIt.c Standard INIT setup; contains main
- entry point; patches all necessary
- traps
- TrapPatches.c Code for the trap patches; same file as
- in the TesterApp Project
-
- The mechanism for calling the traps in SetUpApplication.c is usually
- a menu item. In some cases it might be a dialog with several
- buttons, each of which calls a particular trap. It isn't always
- necessary to patch traps in your TesterApplication. Simply calling
- the routines that implement the guts of the trap patches will often
- be just as good. Having two projects, one that builds the tester
- application and the other that builds the extension, allows you to
- save time debugging and to be able to build the extension at any
- time.
-
- Writing and testing extensions involves multiple rounds of
- 'compiling-installing the INIT-rebooting-Stepping through the INIT in
- a low level debugger'. Use of the two-project method will cut down
- this time.
-
- --
- [8] How do I write a Control Panel-INIT combination?
-
- System extensions generally have no interface. They do what they do
- quietly and the user doesn't want to hear from them. In many cases
- the user needs to set certain preferences. The natural mechanism for
- this is to couple a control panel with an INIT. The problem of
- course is how does the control panel communicate the changes to the
- INIT. I won't discuss the general mechanisms of control panel
- authoring here (see NIM: More Macintosh Toolbox, Chapter 8), but
- there are several mechanisms available for communicating between
- extensions and control panels.
-
- The simplest mechanism and one that will work in the vast majority of
- cases is for the extension to install a Gestalt selector. This
- selector returns the address of a block of memory that holds
- variables that control the actions of the extension. The control
- panel calls the Gestalt selector, retrieves the address of the memory
- block, and alters the values stored in the block as needed. In some
- cases the memory block can contain a function pointer to a function
- in the extension that needs to be called from the control panel.
- Here is some sample code:
-
- typedef struct CommonInfo{
- void (*ResetINIT) (void);//function pointer to reset
- //func
- Boolean On;
- };
-
- #define kSignature 'BLAH' //Should be the sig of the INIT
-
- static CommonInfo gInfo;
-
- /**InstallGestaltSelector****************************************/
- //In the INIT; runs at INIT time
- OSErr
- InstallGestaltSelector(void)
- {
- OSErr err;
-
- err = NewGestalt( kSignature, OurSelector );
-
- if ( err == noErr )
- {
- gInfo.ResetINIT = (void *) ResetFunction;
- gInfo.On = TRUE;
- }
-
- return err;
- }
-
- /**OurSelector**************************************************/
- //In the INIT
- pascal OSErr
- OurSelector( OSType theSelector, long *theResponse )
- {
- SetUpA4();
-
- *theResponse = (long) &gInfo;
-
- RestoreA4();
-
- return noErr;
- }
-
- /**ResetFunction***********************************************/
- //In the INIT
- void
- ResetFunction(void)
- {
- SetUpA4();
-
- //Do something here
-
- RestoreA4();
- }
-
- /**Close********************************************************/
- //In the Control Panel
- void
- Close( Boolean IsOn )
- {
- long result;
- CommonInfo *Info;
-
- //Get address of globals struct from init
- err = Gestalt( kSignature, &result );
- if ( err == noErr )
- {
- Info = (GlobalsType *) result;
- Info->On = IsOn; //Reset OnOff Boolean
- ( * (*Info).ResetINIT) (); //Jump to INIT
- }
- }
-
- If it is possible for an error to occur that prevents the extension
- from resetting itself the ResetFunction should return an error code
- and the control panel should display an alert indicating the problem.
-
- Two additional methods are sometimes used to accomplish communication
- between an extension and a control panel:
-
- The first of these is to write a driver that is installed by the
- extension. The driver holds global variables and will return the
- address of the block of memory holding these variables in response to
- i/o, status, or control calls to the driver. Sample code showing how
- to do this is available in a package called driver-22 written by Pete
- Resnick to be found at:
- ftp://sumex-aim.stanford.edu/info-mac/dev/src/driver-22-c.hqx.gz
-
- The second additional method is to use the PPC toolbox for direct
- communication. There is sample code demonstrating this at:
- ftp://ftp.apple.com/dts/mac/sc/7.0.samples/init-cdev.hqx.
-
- --
- [9] How do I capture keystrokes?
-
- This is accomplished by writing a jGNEFilter function. jGNEFilter
- functions are called from GetNextEvent and WaitNextEvent just before
- those traps return to an application. They are passed a pointer to
- the event record that will be returned to the application. In order
- to capture keystrokes the jGNEFilter would simply check the what
- field of the event record looking for keyboard events and would
- extract the information from the message field if one were found.
-
- The jGNEFilter mechanism is very powerful and is one way that
- screensavers can be implemented. The filter would save the time of
- any keyboard events and would compare the location of the mouse
- against its previous location on null events. If the preset time had
- elapsed during which no keyboard events or mouse movement had
- occurred then the screen saver would activate. A more complete
- discussion of the jGNEFilter is in the next section.
-
- If you are thinking of patching WaitNextEvent or PostEvent in order
- to capture keystrokes or other events, don't. Use a jGNEFilter
- instead. It's easier, it's compatible. It's even documented. See
- the Tech Note 'GetNextEvent; Blinking Apple Menu' (#85).
-
- ftp://ftp.apple.com/dts/mac/tn/toolbox.tb/tb-11-getnextevent.hqx
-
- --
- Brian Stern :-{)}
- Toolbox commando and Menu bard
- Jaeger@fquest.com
-
- ---------------------------
-
- >From Jaeger@fquest.com (Brian Stern)
- Subject: INIT Writing FAQ [2-3]
- Date: 28 Oct 1994 00:42:44 GMT
- Organization: The University of Texas at Austin, Austin, Texas
-
- --
- [10] How can my extension get time periodically?
-
- Installing a jGNEFilter is one method of obtaining periodic time.
- Since the jGNEFilter mechanism is dependent on the event processing
- mechanism, one problem is that no events may be posted if the mouse
- is held down for an extended time.
-
- If your INIT only needs to get time every once in a while then I
- recommend that it only do its thing on null events. On other events
- it should just return. This will have the least impact on the
- machine's performance.
-
- Remember that your jGNEFilter will be called for EVERY event on the
- machine. Do not do a lot of processing on every event or you will be
- slowing down the machine needlessly. Another way to reduce the
- frequency of your extension's processing is to use a simple timer,
- based on TickCount(). In this way your processing is only done, say,
- every 30 or 60 ticks, on null events of course.
-
- Sample code demonstrating jGNEFilters can be found in a package
- called jGNE Helper by Pete Gontier in the alt.sources.mac archive at:
- ftp://ftpbio.bgsu.edu/ftp/pub/alt.sources.mac/vol-
- 01/jgnehelper.cpt.hqx.
-
- Another sample in MPW assembler is at
- ftp://ftp.apple.com/dts/mac/sc/snippets/toolbox/jgnefilter.hqx.
-
- Here's another example that works in Think C:
-
- static ProcPtr gOldGNEFilter;
-
- /****InstallFilter***********************************************/
- //Run this at INIT time
- void
- InstallGNEFilter (void)
- {
- /*Save the ProcPtr to the previous jGNEFilter and insert ours*/
- gOldGNEFilter = JGNEFilter;
- JGNEFilter = (ProcPtr) StripAddress( FilterProc );
-
- }
-
- /****FilterProc**************************************************/
-
- void
- FilterProc(void)
- {
- EventRecord *theEvent;
- long SaveD0;
-
- theEvent = GetA1(); //Move the eventPtr to a variable
- SaveD0 = GetD0(); //Preserve D0
-
- SetUpA4();
-
- switch ( (*theEvent).what ) {
- case nullEvent:
- //Do our thing
- break;
-
- case keyDown:
- //Do something else
- break;
- }
-
- //Execute the previous jGNEFilter
- SetA1( theEvent ); //Restore A1 for the next jGNEFiler
- SetD0( SaveD0); //Restore D0
- SetA0( gOldGNEFilter ); //Put next jGNEFilter in A0
-
- RestoreA4();
-
- asm{
- Unlk A6
- Move.W D0, 4(A7) ;Set Function result on the stack
- JMP (A0) ;Jump to the next jGNEFilter
- }
-
- }
-
- Since a jGNEFilter has access to the actual event record that will be
- returned to the application, the filter can alter the event. The
- most common thing to do is to 'cancel' an event by changing it to a
- null event (Ex. theEvent->what = nullEvent). In this case it should
- also set the value in register D0 to False, or zero.
-
- Here are some additional methods for an extension to get time
- periodically:
-
- If your extension needs more frequent or regular time then can be
- provided by a jGNEFilter then you can install a VBL task or a time
- manager task. Since these run at interrupt time they cannot do
- anything that could move or purge memory. Other methods include
- patching a trap that is called frequently, like SetPort.
-
- A faceless Notification Manager request is another method to get
- time. This is a request that has all the fields in the notification
- record set to NULL except the nmResp field that holds the address of
- your routine to be executed. Your notification response routine will
- be called soon and will be able to move memory. If necessary the
- routine can reinstall itself. This technique is useful for tasks
- that need to be executed once or intermittently. For those tasks
- that need to be executed regularly use one of the other techniques.
-
- You could of course have a faceless NM request that is installed by a
- VBL task or a time manager task.
-
- Use of a faceless background application in concert with an extension
- is yet another method to get time. The fba would do its work on its
- null events.
-
- --
- [11] How should an INIT manage memory?
-
- In general, at INIT time extensions will want to allocate memory in
- the system heap. If you are allocating pointers or handles, use the
- SYS variants, like NewHandleSys() and NewPtrSys(). It is a common
- error to forget this and then to wonder why the INIT crashes. If you
- call NewHandle at INIT time, the handle will be allocated in the
- temporary heap allocated for your extension. If your INIT attempts
- to use it after INIT time the temporary heap will be long gone, along
- with any handles or pointers that had been allocated in it. Any
- attempt to use handles or pointers that no longer exist are
- predictably unpredictable :-)
-
- NewHandle and NewPtr will allocate their memory blocks in the system
- heap if the zone has been set to the system heap, as shown in the
- next paragraph.
-
- If you need to read in resources you can ensure that they go into the
- system heap with something like the following code:
-
- THz saveZone = GetZone();
- SetZone( SystemZone() );
- //read in resources
- SetZone( saveZone );
-
- You will of course need to detach the resources if they need to
- remain in memory after your extension exits. The resource file
- containing your extension will be closed when your extension exits.
-
- If you need to read resources into memory after INIT time you need to
- decide which heap they should go into, either the application heap or
- the system heap. It's a bit hard to make a specific recommendation
- on this but if the resource is something that the application is
- expecting to be read in then it should go into the application heap.
- This would include things like WIND resources in a trap patch to
- GetNewWindow(). The problem of course is that the application heap
- may not have enough room. However, if the resources are private to
- the extension then they should go into the system heap.
-
- It should go without saying that you should always check the error
- codes on memory allocating calls and resource manager calls. If your
- extension is doing something in response to a user action, say making
- a network connection, then it is appropriate to report such errors.
- In many cases however, your extension will simply do nothing in the
- case of out of memory errors or missing resource errors. It is best
- to attempt to allocate all of these things at INIT time and if
- unsuccessful to bail out then.
-
- As mentioned above, MoveHHi doesn't work in the system heap. If you
- intend to allocate a handle that will remain locked for extended
- periods, then call ResrvMem before allocating and locking the handle.
- This will place the handle low in the system heap and help to prevent
- heap fragmentation.
-
- Many toolbox calls are documented as not moving or purging memory and
- as being safe to call at interrupt time. If you are patching one of
- these traps then you must preserve this property. You are guaranteed
- to cause other software to crash if you don't, and your users will
- hate you (once they figure out that it's you). Be aware that the
- only memory manager routine safe to call under these circumstances is
- BlockMove. Also be aware that it is unsafe to access an unlocked
- handle at interrupt time. It is possible that the memory manager is
- in the midst of moving it from one place to another in the heap, and
- the master pointer may not be updated yet.
-
- --
- [12] How do I get my INIT to turn itself off?
-
- An extension might want to turn itself off at INIT time based on its
- preferences setting, or based on a key being pressed or the mouse
- button being pressed, or due to an error during initialization.
- Extensions usually show an icon with a red X through it in this case.
- An extension might also want to turn itself off temporarily after
- INIT time in response to its Control Panel. For instance GateKeeper
- has an on/off switch that turns off virus checking for a set time.
-
- The strategy for temporarily turning off an extension is simply to
- set a global flag and to check it from within the trap patches or
- other parts of the extension. If the flag is off then the trap patch
- simply executes the previous trap. It is generally unsafe to unpatch
- or patch traps after INIT time from an extension. The reason for
- this is that if another extension patches the same trap after you
- have, then it will be jumping to your patch when it has completed its
- work. If you have removed your patch then this calling chain will be
- disrupted and bad things will happen. Also, the Finder patches
- various traps when it loads, which is after INIT time. Disrupting
- those patches would be a very bad thing.
-
- If an extension determines at INIT time that it isn't going to stay
- around then it shouldn't call DetachResource on itself. It's best
- that your extension determine that anything it's dependent on, such
- as resources, specific system Managers, and sufficient memory, are
- present *before* it starts to patch traps and install drivers,
- jGNEFilters and so on. It would be a very bad idea for an extension
- to not detach itself after it had already patched a trap if the trap
- patch resided in the extension.
-
- Many extensions use a particular key press as a signal to indicate
- that the user wants them not to run. Of course the system uses the
- shift key as a signal not to turn on any extensions so you can't use
- that. Some extensions use the option or command keys for this
- purpose. The problem with using those keys is that every time I
- rebuild the desktop those extensions are needlessly inactivated. I
- recommend that the space bar be used for this purpose. Here's some
- sample code:
-
- Boolean
- SpaceBarIsDown(void)
- {
- KeyMap theKeys;
-
- GetKeys( theKeys );
-
- if ( theKeys[1] & 0x00000200 )//Check for spacebar
- return TRUE;
- else
- return FALSE;
-
- }
-
- --
- [13] How do I get my INIT to show it's icon like all the other cool
- inits do?
-
- This is easy. There is code available that does this for you. Get a
- package written by Jim Walker called ShowIcon7 at:
- ftp://mac.archive.umich.edu/mac/development/source/showicon7.sit.hqx
-
- You use it essentially as a plug-in. Just pass in the icon's
- resource ID and it does everything for you. It also shows how to set
- up an A5 world in an extension. You might also take a look at Dair
- Grant's Extension shell package. This one shows how to do animated
- icons.
-
- If your extension decides that it can't install itself then it passes
- the resource ID of an icon that has a red X through it to the
- showicon7 code resource.
-
- Some extensions include the ShowIcon code within their own code
- resources. This code is only about 1K but it seems pointless to me
- for this code to sit in the system heap when it doesn't have to be.
- Use it as a plug-in for your extensions.
-
- --
- [14] How do I show a dialog from my INIT?
-
- First of all, I hate windows of any kind during the startup process.
- If all you want to do is show an alert then use the Notification
- Manager. Your alert will show up when the Finder starts but the user
- will see it and will get whatever message you need to send.
-
- The problem I have with windows at INIT time is that they slow down
- this process and require user interactivity in a process that
- shouldn't do so. Consider the computer that is on 24 hours a day
- doing something important unattended. The power goes off and when it
- comes back on the machine reboots. The user returns several hours
- later to find that the machine is still in the middle of its startup
- because your alert is waiting for a response. Consider also the
- hapless INIT writer who has to reboot his machine 20 times a day.
- Your INIT will not last long on my, um, his machine.
-
- One additional annoyance is that you need to call InitWindows to show
- your window and this erases all the nice INIT icons on the screen. I
- hate that.
-
- Here are a few possible alternatives.
-
- * Play a sound or use the Speech Manager to communicate the
- information.
-
- * Show a different icon during startup to indicate an error. An icon
- with a red X through it is one way to do this. You could also use
- animated icons.
-
- * If you must put up an alert then use a timer so that the alert goes
- away by itself, even if the OK button isn't clicked.
-
- * If you need to interact with the user to get some information, say
- a password for a network connection, then do this once and save the
- results in a preferences file. Provide a Control Panel to change the
- information. Think of Control Panels as the interface for
- extensions.
-
- * Store descriptions of any errors that occur in a preferences file.
- Have the Control Panel display this information. Remember to clear
- this information on each restart and to indicate to the user by sound
- or icon that an error has occurred.
-
- * If you need to communicate error information to the user after INIT
- time then you should definitely use the Notification Manager. For
- example, MacSLIP uses the NM to show an alert indicating that the
- carrier has been lost.
-
- If you still want to show a dialog at INIT time then you need to set
- up an A5 world first. The ShowIcon7 code mentioned above shows how
- to do this. Also see the Tech Note 'Stand-Alone Code' (#256) for an
- explanation and sample code for this and 'Giving the (Desk)Hook to
- INITs' (247) discusses a bug that can appear when showing windows
- from extensions.
- ftp://ftp.apple.com/dts/mac/tn/operating.system.os/os-02-deskhook-
- and-init.hqx
-
- If you do use the Notification Manager from an extension to indicate
- that the extension couldn't load you should use a self-disposing
- Notification request. There are several strategies for doing this.
- I have some code samples for this that will be (have been?) posted to
- alt.sources.mac soon.
-
- --
- [15] How do I maintain compatibility with future systems?
-
- This is tough, and the short answer is that you probably don't.
- You'll notice that Apple comes out with new versions of its
- extensions with each revision of the system. Apple's extensions also
- eventually disappear as their functionality is rolled into the
- system. In all likelihood you'll have to come out with new versions
- of your extensions as new versions of the system come out as well.
-
- Having said all that, there are things you can do to minimize this
- problem. Here are a few suggestions:
-
- * Minimize your reliance on undocumented features of the system.
-
- * Minimize your reliance on low memory globals. Use the Universal
- Header access 'functions' for accessing the low memory globals if
- necessary.
-
- * Use system features like Gestalt, the Process Manager, and the
- Notification Manager to get information about the system, and to
- communicate with the user.
-
- * Try to patch as few traps as possible and use non-patching methods
- whenever possible (e.g., use a jGNEFilter instead of patching
- WaitNextEvent; the filter is more likely to remain compatible than
- your patch).
-
- * Don't use self-modifying code. Self-modifying code changes the
- instructions from what they were compiled as, to something else, at
- run-time. The classic example is to change the address in a JMP
- instruction at run-time so that it jumps to the address of the
- previous trap. This may seem faster than using a global variable but
- it is only slightly faster. It is harder to write, debug, and
- maintain self-modifying code, and it is definitely more likely to
- break with new system releases. If you do use self-modifying code,
- remember to flush the cache. See the tech note 'Cache As Cache Can'
- (#261) for more information on that subject.
-
- * Use the Universal Headers for writing your extensions. This will
- help to ease the transition when it comes.
-
- --
- [16] Any tips for INIT writing?
-
- You may not want your INIT to actually do anything until after INIT
- time. You can find the end of INIT time if you have a jGNEFilter
- installed when the first null event occurs. The Notification Manager
- doesn't usually start processing requests until INIT time is over so
- posting a faceless notification request is another method to find the
- end of INIT time (probably the best if you don't need a jGNEFilter
- for something else). You can also patch Launch to find the end of
- INIT time but this is trickier.
-
- Unfortunately some extension writers do put up windows during INIT
- time. Because of this it's possible that events will occur before
- INIT time is over. To fail-safe the above approaches you also need
- to check for the presence of the Process Manager with a Gestalt call.
- The Process Manager isn't available until after INIT time. If
- Gestalt reports that the Process Manager is not available then you
- need to reinstall your NM request, or simply wait for another event
- to be reported to your jGNEFilter when the Process Manager is
- available.
-
- Here are some utility routines that can reduce the need for 68K
- assembler in your extensions:
-
- pascal void SetA0( void* ) = { 0x205F };
- pascal void SetA1( void* ) = { 0x225F };
- void * GetA0( void ) = { 0x2008 };
- void * GetA7( void ) = { 0x200F };
-
-
- - -------------------------------------------------------------------
-
- Trap Patches:
-
- --
- [17] What exactly is a trap patch?
-
- A trap patch is a method for changing the functionality of a trap.
- The addresses of all the traps are maintained in the two trap
- dispatch tables. By using the routine NSetTrapAddress and friends
- you can change the address of a particular trap to code that you
- provide. When this is done at INIT time, all calls to the patched
- trap from all applications will go to your code, which in most cases
- will do something and then call through the existing trap in the
- ROMs. Be warned that the Finder patches some traps when it starts up
- in a way that prevents previously-installed patches from executing.
-
- I recommend that you read the descriptions of the trap dispatch
- mechanism in the 'Using Assembly Language' chapters in IM I and IV
- and also in the 'Trap Manager' chapter in NIM Operating System
- Utilities.
-
- Traps come in several types based on their parameter passing
- conventions. Most toolbox traps use pascal calling conventions,
- which means that all parameters are passed on the stack and the
- return value, if any, is placed on the stack.
-
- Some traps use register-based calling conventions. In these traps
- the parameters are passed in registers and the return value is
- returned in a register, usually D0. For example all the Memory
- Manager traps are register-based and the File Manager traps are also
- register-based.
-
- Some traps are selector-based. There are only so many spots in the
- trap-dispatch tables. In order to preserve space in these tables
- selector-based traps have been developed. In these traps a single
- trap serves as the front end for a number of system routines. The
- parameters of these traps are passed in the usual manner, either on
- the stack or in registers, and a selector is also passed, usually in
- a register. When the trap is called it checks the selector and then
- dispatches to the appropriate routine. Patching each of these types
- of traps involves different mechanisms. We'll look at samples of
- each one.
-
- Patching traps on the PowerMac is a bit different than on the 68K
- Macs. Most of the discussion here is aimed at patching traps on the
- 68K Macs. Hopefully I'll learn some more about this subject soon and
- there will be some better info here on patching traps on the
- PowerMac.
-
- --
- [18] What's the difference between a head patch and a tail patch?
-
- It is most common to add some functionality to a trap when patching
- it rather than just replacing the existing trap. For instance I've
- written an extension that speaks the text in alerts by using the
- Speech Manager. This works by patching Alert and friends. When
- Alert is called the patch gets the text that appears in the alert and
- passes it to the Speech Manager. The patch then calls the existing
- Alert trap that is in the ROMs. A patch that works in this way is
- called a head patch; it does its business and then it calls the
- previous trap.
-
- A tail patch is a bit different. A virus-checking program might want
- to patch GetResource and then examine the resource that was read in
- to see if it contains a virus. In order to do this the patch must
- first call the existing trap and then do its processing, and finally
- return to the application. This is a tail patch because some
- processing occurs after the existing trap is called. In order for a
- patch to be a head patch you must use a jmp instruction to jump to
- the previous trap. If you use a jsr or a C function pointer to jump
- to the previous trap you have a tail patch.
-
- The reason that this head and tail patch business has been so
- important in the past is because of an Apple invention called the
- come-from patch. Patches were invented, of course, so that Apple
- could fix bugs in the ROMs and could update the routines in the ROMs
- with software. This is why you can run system 7 on a Mac Plus, whose
- ROMs are obviously missing most of the additions made to the toolbox
- in recent years.
-
- Certain ROM routines are particularly large so it is inconvenient to
- patch them if they have bugs in them. To get around this problem the
- Apple programmers searched for smaller routines that are called from
- the large buggy routines and placed patches in the smaller routines.
- These patches check the return address on the stack. If it is the
- address of the buggy routine then a fix is applied. If not then they
- just go on as usual. The patches to these smaller routines are known
- as come-from patches. If you tail patch one of these and then call
- the existing come-from patch, the return address on the stack will be
- in your patch and not the buggy routine that called you. In this
- case the come-from patch will not apply its fix and your system will
- crash.
-
- The good news is that as of system 7 it is safe to apply tail
- patches. The come-from patches still exist in system software, but
- NGetTrapAddress has been modified to return an address that is safe
- to use when applying tail-patches. However, if you wish your
- extension to run in System 6 then tail-patches are not allowed. This
- is documented in the Trap Manager chapter in NIM: OS Utilities.
-
- If you absolutely positively need a tail patch in System 6 then the
- following logic may apply: (Just don't tell anyone that I told you
- this :-) Apple is not releasing any new versions of System 6 so no
- new come-from patches will be forthcoming for System 6. If you do
- careful testing of the traps you wish to tail-patch you will probably
- be OK. In general traps not called from the ROMs, like Alert and
- MenuKey, will not contain come-from patches.
-
- One final thing: In system 7 it is safe to apply tail-patches to all
- traps except FrontWindow.
-
- --
- [19] How do I patch a trap?
-
- Here is some sample code for a head patch of Alert, a stack-based
- trap:
-
- TrapPtr gOldAlertTrapAddress;
-
- /****InstallPatch***************************************************/
-
- void
- InstallPatch (void)
- {
- gOldAlertTrapAddress = GetToolTrapAddress( _Alert );
- SetToolTrapAddress( (long) AlertPatch, _Alert );
- }
-
- /****AlertPatch***************************************************/
-
- pascal void
- AlertPatch( short alertID, ProcPtr filterProcPtr )
- {
- SetUpA4();
-
- MyAlert( alertID) ; //Do our thing
-
- //store the correct alert addr
- //in A0 while we can still access globals via A4
-
- asm { move.l gOldAlertTrapAddress, A0 }
-
- RestoreA4();
-
- asm {
- unlk A6 //match the link generated by C
- jmp (A0) //jump to _Alert
- }
- }
-
- There are a number of details to note here. This patch is of course
- part of a code resource that is loaded at INIT time and detached as
- described in an earlier section. The routine InstallPatch must be
- called at INIT time.
-
- The routines GetToolTrapAddress and SetToolTrapAddress allow you to
- get and set the addresses of Tool Traps. The similar routines
- GetOSTrapAddress and SetOSTrapAddress allow you to manipulate the
- addresses of OS traps. The routines NGetTrapAddress and
- NSetTrapAddress allow you to manipulate the addresses of either,
- although they call glue code. I recommend that you use the
- GetXTrapAddress and SetXTrapAddress calls. There are two obsolete
- calls: GetTrapAddress and SetTrapAddress. Don't use them.
-
- The prototype for this patch is declared as 'pascal void' while the
- prototype for Alert is 'pascal short'. Because this is a head patch
- it will not be returning a result; the result will be returned from
- the real Alert trap. The pascal keyword is used to indicate pascal
- calling conventions. It is not strictly required in all cases but
- does no harm.
-
- The Think C routines SetUpA4 and RestoreA4 are called to allow access
- to global variables by A4 addressing. In this case
- gOldAlertTrapAddress is the only global variable we are addressing,
- unless any are used inside MyAlert. Note that this variable is moved
- to A0 while access to global variables is still available. In some
- cases one might move a global variable to a local variable, which
- doesn't rely on A4 addressing. A4 could then be restored and the old
- trap address could be loaded into A0 later in the code.
-
- Because there is a parameter list the compiler generates a Link A6
- instruction at the start of this function. In order to restore the
- stack a matching Unlk A6 must be placed at the end of the function.
- Since we are exiting by the jmp (A0) we must insert the Unlk A6
- ourselves. The compiler does generate an Unlk A6 and an RTS at the
- end of this function, but they will never be executed. The presence
- of the Link A6 instruction is dependent on the particular compiler
- you use and on its rules for generating a stack frame. It is a good
- idea to disassemble the code for your trap patches to see whether a
- stack frame has been generated in order to determine if you need to
- insert the Unlk A6 instruction. If you don't match the Link A6 with
- an Unlk A6 the stack will be screwed up.
-
- It is essential that the stack look exactly the same on exit from a
- head patch as it does on entry. If not you will surely crash. (If
- you had good reason you could modify the value of a parameter on the
- stack, but that's another story.) This patch saves and restores A4
- but does modify A0 and A1 (SetUpA4 uses A1). In general, with head
- patches of stack-based traps you can modify A0, A1, D0, D1, and D2,
- but not any other registers. You may need to look at the
- disassembled code to be sure that all your registers are properly
- saved and restored.
-
- The design of the patch as shown here, with the patch code calling a
- separate function to perform the actual functionality of the patch is
- a good design to follow with all but the simplest of patches.
-
- You might think that you need to call StripAddress on the address of
- the patch routine before passing this address to SetToolTrapAddress.
- This is not necessary unless the address is actually a handle. If
- you were to load a code resource and pass its entry point to
- SetToolTrapAddress then it would need to be stripped.
-
- --
- Brian Stern :-{)}
- Toolbox commando and Menu bard
- Jaeger@fquest.com
-
- ---------------------------
-
- >From Jaeger@fquest.com (Brian Stern)
- Subject: INIT Writing FAQ [3-3]
- Date: 28 Oct 1994 00:44:27 GMT
- Organization: The University of Texas at Austin, Austin, Texas
-
- --
- [20] How do I patch a register-based trap?
-
- Here is the code for a sample register-based trap patch:
-
- TrapPtr gMountVolAddress;
-
- /****InstallPatch**************************************************/
-
- void
- InstallPatch(void)
- {
- gMountVolAddress = GetOSTrapAddress( _MountVol );
- SetOSTrapAddress( (long) MountVolPatch, _MountVol );
- }
-
- /****MountVolPatch**************************************************
-
- This is a register-based trap that has A0 set to point to its
- parameter
- block on entry. The prototype for MountVol is:
-
- pascal OSErr PBMountVol( ParmBlkPtr paramBlock )
-
- This patch beeps when a floppy or CD-ROM is inserted or when a
- harddrive is mounted by the Finder.
-
- *******************************************************************/
-
- pascal void
- MountVolPatch(void)
- {
- //Save some registers
- //Save A0 since it's trashed by SetUpA4
- //D1 contains the trap word
-
- asm { movem.l a0/d0-d1, -(sp) }
-
- SetUpA4(); //Allow access to global variables
-
- SysBeep( 5 ); //The guts of our head patch
-
- //store the correct MountVol addr
- //in A1 while we can still access globals via A4
- asm { move.l gMountVolAddress, A1 }
-
- RestoreA4(); //Restore previous value in A4
-
- asm { //Restore the registers
- movem.l (sp)+, a0/d0-d1
- jmp (A1) //jump to _MountVol
- }
-
- }
-
- This head patch is similar in structure to the patch to Alert with a
- few differences. The prototype uses no parameters and has no return
- value. The single parameter is passed through A0. This patch doesn't
- do anything with this value but it could be moved to a local variable
- and then used to reference the fields in the parameter block if
- desired. Access to global variables is by the same A4 mechanism as
- in the Alert patch. Note that _MountVol is an OS trap so
- GetOSTrapAddress and SetOSTrapAddress are used to set up the patch.
-
- Since A0 is used to pass the parameter to this trap we jump to the
- real _MountVol trap through A1.
-
- Obviously A0 must be saved and restored in this patch. OS traps
- expect to find the trap word in D1 so it must be saved and restored
- as well. Three registers, A0, D0, and D1, are saved onto the stack
- with the movem instruction, and restored at the end of the patch.
-
- Think C doesn't generate a 'Link A6' at the start of this function
- because there are no parameters and no local variables. Because of
- this no 'Unlk A6' is needed at the end of the function.
-
- --
- [21] Can you show me an example tail patch?
-
- Here is another example of a patch to a register-based trap. This
- sample is a tail patch and is dependent on the CodeWarrior
- environment. Because CW allows you to specify that parameters are
- passed in registers this trap patch requires no assembly.
-
- extern pascal OSErr (*Old_MountVol)( ParmBlkPtr pb : __A0 ) : __D0;
-
- pascal OSErr My_MountVol( ParmBlkPtr pb : __A0 ) : __D0
- {
- OSErr err;
- long saveA4 = SetCurrentA4();
-
- err = Old_MountVol( pb );
- DoSomthingFunc();
-
- SetA4( saveA4 );
- return err;
- }
-
- --
- [22] How do I patch a selector-based trap?
-
- Here is a sample patch to PrGlue. This trap is the front end for all
- the Printing Manager routines. Its selector is pushed on the stack
-
- typedef struct
- {
- long Selector;
- THPrint hPrint;
- } PrJobDialogStack;
-
- TrapPtr PrGlueAddress;
-
- /****InstallPatch****************************************************
- /
-
- void
- InstallPatch(void)
- {
- PrGlueAddress = GetToolTrapAddress( _PrGlue );
- SetToolTrapAddress( (long) PrGluePatch, _PrGlue );
- }
-
- /****PrGluePatch****************************************************
-
- This is a stack-based trap with a long word selector also pushed
- onto the stack. On entry the selector is at 4(A7). The return
- address is at 0(A7). After the 'Link A6' the selector is at 12(A7).
-
- *******************************************************************/
-
- #define kSelectorOffset 12
- #define kPrJobDialogSelector 0x32040488
-
- pascal void
- PrGluePatch(void)
- {
- PrJobDialogStack *StackPtr;
-
- //Get address of the stack frame
- //and save it in a local variable
-
- asm {
- lea kSelectorOffset(A7), A0
- move.l A0, StackPtr
- }
-
- SetUpA4(); //Allow access to global variables
-
- //Check the selector
- if ( StackPtr->Selector == kPrJobDialogSelector )
- {
- SysBeep( 5 );
-
- //Pass hPrint to our function to do something
- DoSomethingFunc( StackPtr->hPrint );
- }
-
- //Store the correct PrGlue addr
- //in A0 while can still access globals via A4
- asm { move.l PrGlueAddress, A0 }
-
- RestoreA4(); //Restore previous value in A4
-
- asm {
- unlk A6 //match C's Link A6
- jmp (A0) //jump to _PrGlue
- }
-
- }
-
- In order to access the selector and the parameters for PrGlue we use
- a pointer to a struct. Once the pointer is initialized correctly we
- can access the selector and any parameters from C easily.
-
- According to NIM: PPC System Software it is not safe to patch
- selector-based traps with PPC native code. All patches of selector-
- based traps on the PowerMac should be written in 68K code.
-
- --
- [23] How do I patch a trap on the PPC?
-
- See NIM 'PowerPC System Software' for a more complete discussion.
- There is also a new book by Tom Thomson called 'Power Macintosh
- Programming Starter Kit' that has examples of how to patch traps on
- the PowerMac.
-
- Patching traps on the PowerMac is similar to patching on the 68K
- architecture. Of course you must generate a UniversalProcPtr for
- each of your patches in the system heap, and these are then passed to
- the SetXTrapAddress routines. Since code fragments have their own
- globals the use of A4 or A5-based mechanisms for accessing global
- variables isn't needed. In order to call the previous trap you need
- to call CallUniversalProc or CallOSTrapUniversalProc and return its
- result from your patch. As a result all patches on the PowerMac are
- tail patches.
-
- You may find an application called 'Traps Check' useful. This app
- supplies a report about all the traps on a Powermac, indicating
- whether each trap is emulated or native. Another way to do this is
- to drop into MacsBug and disassemble from the address of the trap
- you're interested in (e.g., 'il CopyBits' ). For traps that are
- native you'll see a routine descriptor that begins with the
- MixedModeMagic trap (AAFE). This of course won't tell you if the trap
- has been patched. You can identify a patch by whether it's in RAM or
- ROM, from its address. Determining whether a patched trap is PPC
- native or not may take some additioinal sleuthing. You can find Traps
- Check at: ftp://sumex-aim.stanford.edu/info-mac/dev/traps-check-
- 10.hqx
-
- Here is a sample PowerMac trap patch for GetResource:
-
- UniversalProcPtr gGetResourceUPP;
- UniversalProcPtr gGetResourcePatchUPP;
-
- /****InstallPatch**************************************************/
-
- void
- InstallPatch(void)
- {
- gGetResourceUPP = GetToolTrapAddress( _GetResource );
-
- gGetResourcePatchUPP =
- NewRoutineDescriptor( (ProcPtr) GetResourcePatch,
- kPascalStackBased, GetCurrentISA() );
-
- SetToolTrapAddress( gGetResourcePatchUPP, _GetResource );
-
- }
-
-
- /****GetResourcePatch*********************************************/
-
- Handle
- GetResourcePatch( ResType theType, short theID )
- {
- Handle result;
-
- //We don't need no 'DUMB' resources
- if ( theType == 'DUMB' )
- result = NULL;
- else
- result = (Handle) CallUniversalProc( gGetResourceUPP,
- kGetResourceProcInfo, theType, theID );
-
- return result;
-
- }
-
- --
- [24] Can I write a fat trap?
-
- //Under construction
-
- --
- [25] Tips?
-
- If your patch isn't called you may have guessed wrong on whether it's
- a ToolTrap or an OSTrap. The high bit of the second byte of the trap
- word is set for ToolTraps. The following function can be used to get
- the correct trap address for both ToolTraps and OSTraps.
-
- pascal void * GetCurrentTrapAddress( unsigned short trapWord )
- {
- if ( trapWord & 0x0800 )
- return GetToolTrapAddress ( trapWord & 0x07FF );
- else
- return GetOSTrapAddress ( trapWord & 0x07FF );
- }
-
-
- If the machine crashes after leaving your patch you have probably
- munged the stack or not saved and restored all the registers that you
- must.
-
- The Finder patches a number of traps when it loads in a way that
- prevents earlier trap patches from functioning. If your patch
- doesn't appear to be called it may be one of these patches.
-
- --
- [26] What other sources of information are available?
-
- Knaster 'How to Write Macintosh Software'
- Knaster and Rollin, 'Macintosh Programming Secrets'. These books on
- Mac programming has some excellent info on trap patching.
-
- Tom Thomson 'Power Macintosh Programming Starter Kit' This book has
- some example code for writing trap patches and extensions on the
- PowerMac.
-
- The Extension Shell package at:
- ftp://sumex-aim.stanford.edu/info-mac/dev/src/extension-shell-13.hqx
- Dair's email address has changed to: dair.grant@ucl.ac.uk.
-
- Usenet Macintosh Programmers Guide
- ftp://sumex-aim.stanford.edu/info-mac/dev/info/usenet-mac-prog-guide-
- msw.hqx
-
- All of the Apple Tech Notes have been made available on Apple's web
- server: http://www.info.apple.com/dev/technotes/Main.html
-
- --
- Brian Stern :-{)}
- Toolbox commando and Menu bard
- Jaeger@fquest.com
-
- ---------------------------
-
- >From shawnl@andyne.on.ca (Dave Charlesworth)
- Subject: Linking 68k object files to PPC program
- Date: Thu, 27 Oct 1994 19:26:03 GMT
- Organization: Andyne Computing
-
- I want to link some third party code to a PowerPC program. Can someone
- point me to documentation on how to make this work?
-
- I don't have source for the third party stuff. I'm using MPW (ETO 15)
- cross- platform tools (PPCLink, PPCC), and have the Inside Mac volume
- "PowerPC System Software". I haven't been able to find anything in it
- or in the ETO documentation, but it must be somewhere!
-
- Thanks.
-
- Shawn Leclaire
-
- +++++++++++++++++++++++++++
-
- >From zellers@pokey.basilsoft.com (Steve Zellers)
- Date: Fri, 28 Oct 1994 20:52:49 -0800
- Organization: BasilSoft, Inc.
-
- In article <CyCJBF.Ms4@andyne.on.ca>, shawnl@andyne.on.ca (Dave
- Charlesworth) wrote:
-
- > I want to link some third party code to a PowerPC program. Can someone
- > point me to documentation on how to make this work?
-
- Assuming you mean that the third party code is 68k, you can't. You'll
- have to write a stub code resource that re-exports all the symbols you
- need through a paramblock as some sort using route descriptors.
-
- --smz
-
- +++++++++++++++++++++++++++
-
- >From wdh@fresh.com (Bill Hofmann)
- Date: Sat, 29 Oct 1994 18:27:36 GMT
- Organization: Fresh Software
-
- In article <CyCJBF.Ms4@andyne.on.ca>, shawnl@andyne.on.ca (Dave
- Charlesworth) wrote:
-
- > I want to link some third party code to a PowerPC program. Can someone
- > point me to documentation on how to make this work?
- >
- > I don't have source for the third party stuff. I'm using MPW (ETO 15)
- > cross- platform tools (PPCLink, PPCC), and have the Inside Mac volume
- > "PowerPC System Software". I haven't been able to find anything in it
- > or in the ETO documentation, but it must be somewhere!
- >
- Nope, not really. Maybe some of the MacTech articles have mentioned it.
- But what you have to do is:
- * find out which routines *you* call in the library
- * write some 68k code that wraps the library in a way that you can
- call it: either use a selector-based approach (ie, if message==1,
- call function 1, etc) or make a routine that returns a table of
- procptrs
- * compile/link the wrapper with the library
- * create proc infos and stub code to call your 68k wrapper in your
- PowerPC program
- * debug :->
-
- Or, yell at the third party until they produce a PowerPC version (shared
- library, or whatever).
-
- -Bill
-
- --
- Bill Hofmann wdh@fresh.com
- Fresh Software and Instructional Design voice: +1 510 524 0852
- 1640 San Pablo Ave #C, Berkeley CA 94702 USA fax: +1 510 524 0853
-
- ---------------------------
-
- >From rjkmehta@bu.edu (Ravi Mehta)
- Subject: Network Programming
- Date: 19 Oct 1994 16:20:21 GMT
- Organization: Boston University
-
- I want to write some networkable software, but am completely new to network
- programming. Besdies IM: Networking ( which I will pickup ) is there
- anything else that would help? Will IM: Networking discuss programming
- for BOTH AppleTalk and Ethernet? If not, what would be a good
- source for learning how to write Ethernet and AppleTalk compatible software.
-
- Thanks in advance.
-
- Ravi J. K. Mehta
- Terminal Sunset Software
-
-
- +++++++++++++++++++++++++++
-
- >From andym96@aol.com (AndyM96)
- Date: 20 Oct 1994 01:13:05 -0400
- Organization: America Online, Inc. (1-800-827-6364)
-
- In article <383h05$a37@news.bu.edu>, rjkmehta@bu.edu (Ravi Mehta) writes:
-
- <<
- Will IM: Networking discuss programming
- for BOTH AppleTalk and Ethernet? If not, what would be a good
- source for learning how to write Ethernet and AppleTalk compatible
- software.>>
- yes, IM networking discusses how to do that. Also, a good book is
- "Programming with AppleTalk" by Michael Peirce -code samples are in
- Pascal, though, but it is a thorough and detailed description of how
- AppleTalk protocols work & how to use 'em.
- BTW, if you dicover a code sample how to write a requester-responder pair
- using ATP in C, <<PLEASE>> e-mail me @ andym96@aol.com -I've been trying
- to get this info for a couple of weeks now with no avail.
- Andy
-
- +++++++++++++++++++++++++++
-
- >From ntuck@muddcs.cs.hmc.edu (Nathan D. Tuck)
- Date: 20 Oct 1994 20:02:38 GMT
- Organization: Harvey Mudd College, Claremont CA
-
-
- >In article <383h05$a37@news.bu.edu>, rjkmehta@bu.edu (Ravi Mehta) writes:
- >
-
- >Will IM: Networking discuss programming
- >for BOTH AppleTalk and Ethernet? If not, what would be a good
- >source for learning how to write Ethernet and AppleTalk compatible
- >software.>>
-
- For both AppleTalk and Ethernet? AppleTalk is a software protocol while
- Ethernet is the physical format that AppleTalk runs over. If you mean
- LocalTalk and Ethernet, the two should be equivalent so far as ATP
- API's are concerned. If you mean to run transparantly over different
- protocol stacks such as ATP and IPX/SPX or TCP/IP, that is another
- question entirely.
-
- Nate
- ntuck@hmc.edu
-
-
-
- +++++++++++++++++++++++++++
-
- >From Yorick_Ph*nix,MacTel_Iconex@metro.mactel.org (Yorick
- Ph*nix,MacTel_Iconex)
- Date: 29 Oct 1994 02:48:38 GMT
- Organization: MacTel Metro BBS, London, England.
-
- Ravi
-
- > I want to write some networkable software, but am completely new to
- > network programming. Besdies IM: Networking ( which I will pickup )
- > is there anything else that would help?
-
- There is a very good book called something like Introduction to AppleTalk
- Programming - I have a copy at the office and I learnt all my Network
- Programming from it. It is possibly published by Addison-Wesley and is one in
- a series where Scott Knaster is the Series Editor.
-
- AppleTalk programming is what you should be doing (ATP, NBP, ADSP, PAP, etc)
- whereas LocalTalk and EtherNet are the phsyical mediums over which the
- network data travels - you shouldnt need to get involved at this level or
- even know which phsyical medium your program is dealing with.
-
- Yorick
-
- - sent via an evaluation copy of BulkRate (unregistered).
-
- --
- ****************************************************************************
- MacTel Metro - Europes largest Mac specific BBS
- The views expressed in this posting those of the individual author only.
- Send mail to this user at either :-
- INTERNET:User_Name@metro.mactel.org [use underline] between first
- FIDONET:User.Name@f202.n254.z2.fidonet.org [use fullstop ] & last names
- ****************************************************************************
-
- ---------------------------
-
- >From walkerj@math.scarolina.edu (James W. Walker)
- Subject: Stuck in SyncWait again
- Date: Sat, 15 Oct 1994 21:39:18 -0500
- Organization: Dept. of Mathematics, Univ. of South Carolina
-
- When an application freezes, dropping into MacsBug often reveals that it
- is stuck in SyncWait. When that happens, typing es to MacsBug or using
- force-quit does nothing. Is there any hope for someone with debugger
- skills slightly below those of "Kon & Bal" to get the app out of SyncWait
- and make it die a clean death, or should I just restart the Mac?
- --
- Jim Walker
-
- +++++++++++++++++++++++++++
-
- >From jonasw@lysator.liu.se (Jonas Wallden)
- Date: 16 Oct 1994 09:57:15 GMT
- Organization: (none)
-
- walkerj@math.scarolina.edu (James W. Walker) writes:
-
- >When an application freezes, dropping into MacsBug often reveals that it
- >is stuck in SyncWait. When that happens, typing es to MacsBug or using
- >force-quit does nothing. Is there any hope for someone with debugger
- >skills slightly below those of "Kon & Bal" to get the app out of SyncWait
- >and make it die a clean death, or should I just restart the Mac?
- >--
- > Jim Walker
-
- The SyncWait loop waits for a parameter block error code to drop below +1
- (which is the value used while the call is in progress), and as we all know
- this error code is 0 (noErr) for a successful request and negative for
- errors.
-
- So, look at the SyncWait code to see which word it tests (usually something
- like 10(A0)) and set this word to an error code (e.g. FFD5 for fileNotFound)
- and it will often get you out of the lock.
-
- I've used it successfully in Mosaic several times where it seems to hang
- when I abort a connection, and at other times when the computer won't
- reboot after a crash.
-
- BTW, I have a MacsBug dcmd which lists error strings from error codes.
- This is great as it's rather difficult to use ObiWan at these times...
- Can't remember if I got it from sumex or a Developer CD, though.
-
- --
- `.`. Jonas Wallden `.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.
- `.`.`. Internet: jonasw@lysator.liu.se `.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.
- `.`.`.`. AppleLink: sw1369 `.`.`.`.`.`.`.`.`.`.`.`.`.`.`.
-
- +++++++++++++++++++++++++++
-
- >From wysocki@netcom.com (Chris Wysocki)
- Date: Sun, 16 Oct 1994 16:31:58 GMT
- Organization: NETCOM On-line Communication Services (408 261-4700 guest)
-
- In article <walkerj-1510942139180001@192.0.2.1>,
- James W. Walker <walkerj@math.scarolina.edu> wrote:
-
- >When an application freezes, dropping into MacsBug often reveals that it
- >is stuck in SyncWait. When that happens, typing es to MacsBug or using
- >force-quit does nothing. Is there any hope for someone with debugger
- >skills slightly below those of "Kon & Bal" to get the app out of SyncWait
- >and make it die a clean death, or should I just restart the Mac?
-
- Here's a MacsBug dcmd that I wrote a few weeks ago that simply does a
- KillIO for a specified driver. You might be able to use this when
- you're stuck in _SyncWait to kill the pending request and get out
- safely. Since it's so small, I've attached it below, along with the
- source code to it; hope you find it useful.
-
- Chris.
-
- - ------
-
- +++++++++++++++++++++++++++
-
- >From h+@nada.kth.se (Jon W{tte)
- Date: Sun, 16 Oct 1994 20:15:31 +0100
- Organization: Royal Institute of Something or other
-
- In article <walkerj-1510942139180001@192.0.2.1>,
- walkerj@math.scarolina.edu (James W. Walker) wrote:
-
- >When an application freezes, dropping into MacsBug often reveals that it
- >is stuck in SyncWait. When that happens, typing es to MacsBug or using
- >force-quit does nothing. Is there any hope for someone with debugger
- >skills slightly below those of "Kon & Bal" to get the app out of SyncWait
- >and make it die a clean death, or should I just restart the Mac?
-
- Usually this means a SCSI request isn't being served (or an
- Ethernet request, or a Serial Port request, or...) This is
- usually caused because of buggy drivers (like early Applied
- Engineering drivers, some CD-ROM and MO drivers and version 1.x
- of the Digidesign card drivers)
-
- When something hangs in _vSyncWait, it waits for the word at
- (a0)+10 to go 0 or negative (this is ioResult in the parameter
- block) One thing you can TRY is:
-
- atba
- sw a0+10 ffff
- g
- atc
- es
-
- This will make the app halt as soon as it gets to an A-trap (so
- it won't just get stuck again) Then it fakes an interrupt
- service routine that sets the result to -1 (an error code) Run
- with this; and as soon as an A-trap is hit, clear breaks and
- exit.
-
- However, since this is a driver that got hosed, chances are
- you'll run into the same problem an instant later, so it's
- usually not terribly helpful.
-
- There are also several conditions which can make this fail:
-
- - If some idiot masked interrupts, that's the reason you're
- waiting for an interrupt that's never serviced. Check with TD
- and look at the Int= figure - should be 0. 7 is real bad.
-
- - If this was because of a file manager request; the file
- manager is now in a meeting for the rest of the day, which
- means you earned just about nothing by breaking out.
-
- - If the driver makes interesting assumptions about the return
- value you use (ffff==-1 in this case) OR wants a completion
- routine to be called, you're probably hosed anyway.
-
- There should be a law only competent people can write drivers.
- Unfortunately it seems to be the other way around with some
- people "Hey, we've got this interesting hardware we can sell.
- However, hiring someone expensive to write the drivers would
- eat into our margin way too much. Isn't Joes 13-year-old kid
- into computers? Have him whip something up and we'll give him a
- Happy Meal."
-
- Hardware without drivers is pretty useless.
-
- Cheers,
-
- / h+
-
-
- --
- Jon W$E4tte (h+@nada.kth.se), Hagagatan 1, 113 48 Stockholm, Sweden
-
- -- I don't fear death, it's dying that scares me.
-
-
- +++++++++++++++++++++++++++
-
- >From jumplong@aol.com (Jump Long)
- Date: 17 Oct 1994 00:44:01 -0400
- Organization: America Online, Inc. (1-800-827-6364)
-
- In article <walkerj-1510942139180001@192.0.2.1>,
- walkerj@math.scarolina.edu (James W. Walker) wrote:
-
- >When an application freezes, dropping into MacsBug often reveals that it
- >is stuck in SyncWait. When that happens, typing es to MacsBug or using
- >force-quit does nothing. Is there any hope for someone with debugger
- >skills slightly below those of "Kon & Bal" to get the app out of SyncWait
- >and make it die a clean death, or should I just restart the Mac?
-
- Here are a couple of paragraphs from the article "Asynchronous Routines on
- the Macintosh" in develop issue #13 that explain deadlock conditions and
- SyncWait:
-
- - ----
-
- Avoid SyncWait.
-
- Does your Macintosh just sit there not responding to user events? Drop
- into the debugger and take a look at the code that's executing. Does it
- look like this?
-
- MOVE.W $0010(A0),D0
- BGT.S -$04,(PC)
-
- That's SyncWait, the routine that synchronous calls sit in while waiting
- for a request to complete. Register A0 points to the parameter block used
- to make the call, offset $10 is the ioResult field of the parameter block,
- and SyncWait is waiting for ioResult to be less than or equal to 0
- (noErr).
-
- The ioResult field is changed by code executing as a result of an
- interrupt. If interrupts are disabled (because the synchronous call was
- made at interrupt time) or if the synchronous call was made to a service
- that's busy, you'll be in SyncWait forever. Take a look at the parameter
- block and where it is in memory, and you'll probably be able to figure out
- which synchronous call was made at interrupt time and which program made
- it.
-
- - ---
-
- Deadlock is a state in which each of two or more processes is waiting for
- one of the other processes to release some resource necessary for its
- completion. The resource may be a file, a global variable, or even the
- CPU. The process could, for example, be an application's main event loop
- or a Time Manager task.
-
- When deadlock occurs on the Macintosh, usually at least one of the
- processes is executing as the result of an interrupt. VBL tasks, Time
- Manager tasks, Deferred Task Manager tasks, completion routines, and
- interrupt handlers can all interrupt an application's main thread of
- execution. When the interrupted process is using a resource that the
- interrupting process needs, the processes are deadlocked.
-
- For example, suppose a Time Manager task periodically writes data to a
- file by making a synchronous Write request, and an application reads the
- data from its main event loop. Depending on the frequency of the task and
- the activity level of the File Manager, the Time Manager task may often
- write successfully. Inevitably, however, the Time Manager task will
- interrupt the application's Read request and deadlock will occur.
-
- Because the File Manager processes only one request at a time, any
- subsequent requests must wait for the current request to complete. In this
- case, the synchronous request made by the Time Manager task must wait for
- the application's Read request to complete before its Write request will
- be processed. Unfortunately, the File Manager must wait for the Time
- Manager task to complete before it can resume execution. Each process is
- now waiting for the other to complete, and they will continue to wait
- forever.
-
- Synchronous requests at interrupt time tend to produce deadlock, because
- the call is queued for processing and then the CPU sits and spins, waiting
- for an interrupt to occur, which signals that the request has been
- completed. If interrupts are turned off, or if a previous pending request
- can't finish because it's waiting to resume execution after the interrupt,
- the CPU will wait patiently (and eternally) for the request to finish -
- until you yank the power cord from the wall.
-
- - ---
-
- Read the rest of that article, it'll help you write code that doesn't end
- up in SyncWait.
-
- - Jim Luther
-
-
- +++++++++++++++++++++++++++
-
- >From walkerj@math.scarolina.edu (James W. Walker)
- Date: Mon, 17 Oct 1994 23:41:46 -0500
- Organization: Dept. of Mathematics, Univ. of South Carolina
-
- In article <37sveh$t0t@newsbf01.news.aol.com>, jumplong@aol.com (Jump
- Long) wrote:
-
- > Read the rest of that article, it'll help you write code that doesn't end
- > up in SyncWait.
-
- I guess I didn't make it clear in my original post, but it's not *my* code
- that gets stuck in SyncWait. It's usually Internet apps like Anarchie. I
- was just wondering whether there was anything I could do when it happens,
- other than restart, and this thread has given me some ideas. Gee, I can
- hardly wait for the next freeze. :-)
- --
- Jim Walker
-
- +++++++++++++++++++++++++++
-
- >From bierman@caelab1.cae.wisc.edu (Peter Bierman)
- Date: Tue, 18 Oct 1994 14:36:31 -0600
- Organization: Happy Frogs, Inc.
-
- In article <walkerj-1710942341460001@192.0.2.1>,
- walkerj@math.scarolina.edu (James W. Walker) wrote:
-
- > In article <37sveh$t0t@newsbf01.news.aol.com>, jumplong@aol.com (Jump
- > Long) wrote:
- >
- > > Read the rest of that article, it'll help you write code that doesn't end
- > > up in SyncWait.
- >
- > I guess I didn't make it clear in my original post, but it's not *my* code
- > that gets stuck in SyncWait. It's usually Internet apps like Anarchie. I
- > was just wondering whether there was anything I could do when it happens,
- > other than restart, and this thread has given me some ideas. Gee, I can
- > hardly wait for the next freeze. :-)
-
-
- Well, all of the ideas are good and accurate, but here's an easy fix.
-
- Do a step (oa-T) till Macsbug says "Will [not] branch". Then type:
-
- pc=pc+2
-
- g
-
- That will jump you out of the loop. It's faster than "fixing" the loop
- condition. Just note that what John said is true: it'll probobly happen
- again withing a short time. Restart right away.
-
- -Peter
-
- --
- Peter Bierman \ The Metropolis \ The most primitive part of
- the
- bierman@caelab1.cae.wisc.edu\ (614)-846-1911 \ the brain concerns itself
- \ 600MB Mac Files \ with the "Four F's":
- "I've changed my mind, Hobbes.\ FirstClass GUI \ Feeding, Fighting,
- Fleeing,
- people are scum." --Calvin \ Info-Mac CD-ROM \ and Reproduction.
-
- +++++++++++++++++++++++++++
-
- >From richardb@cocytus.demon.co.uk (Richard Buckle)
- Date: Wed, 19 Oct 1994 06:37:42 GMT
- Organization: none
-
- In article <AAC73A63966886B32@klkmac003.nada.kth.se>,
- h+@nada.kth.se (Jon W{tte) wrote:
-
- >>When an application freezes, dropping into MacsBug often reveals that it
- >>is stuck in SyncWait. When that happens, typing es to MacsBug or using
- >>force-quit does nothing. Is there any hope for someone with debugger
- >>skills slightly below those of "Kon & Bal" to get the app out of SyncWait
- >>and make it die a clean death, or should I just restart the Mac?
-
- To be honest you can often get away with stepping over the SyncWait test if
- you restart *immediately* you regain control.
-
- In MacsBug, do a T 40. This should pop you out of any subroutines you're in
- and leave you in the 2-step SyncWait loop; if not, keep doing T 40 until
- you are. If you're at the TST instruction, do one more T to get to the
- branch instruction. Then do PC=PC+2;G to exit the loop.
-
- You may need to repeat this process one or more times to regain control.
- Once you have control, go straight to the Finder and to a Restart before
- the driver can bite you again.
-
- No guarantees and YMMV. However, 90% of the tine this lets be save my work
- :-|
-
-
-
- - -----------------------------------------------------
- Richard Buckle
- richardb@cocytus.demon.co.uk
- Using this darned fine NewsHopper thingy.
-
-
- +++++++++++++++++++++++++++
-
- >From quinn@cs.uwa.edu.au (Quinn "The Eskimo!")
- Date: Fri, 28 Oct 1994 10:13:36 +0800
- Organization: Department of Computer Science, The University of Western
- Australia
-
- In article <walkerj-1710942341460001@192.0.2.1>,
- walkerj@math.scarolina.edu (James W. Walker) wrote:
-
- >I guess I didn't make it clear in my original post, but it's not *my* code
- >that gets stuck in SyncWait. It's usually Internet apps like Anarchie.
-
- For reliable program (like Anarchie :) disappearing into SyncWait normally
- means that your networking on your machine is stuffed up somehow.
-
- To get out try this in MacsBug...
-
- sm a0+10 ffff
- g
-
- What it does is set the ioResult field of the paramblock to -1, indicating
- an error. You often have to do it a *lot* of times before it comes back
- and often it doesn't work at all. But it makes you feel like you've got
- control (:
-
- Share and Enjoy.
- --
- Quinn "The Eskimo!" "I wasn't the one who fired the heat seeking
- population annihilator out the window!"
- Amaze your friends! Learn some cool MacsBug or MicroBug commands today (:
-
- +++++++++++++++++++++++++++
-
- >From devon_hubbard@taligent.com (Devon Hubbard)
- Date: Fri, 28 Oct 1994 16:20:48 GMT
- Organization: Taligent, Inc.
-
- In article <quinn-2810941013360001@mac168.cs.uwa.oz.au>,
- quinn@cs.uwa.edu.au (Quinn "The Eskimo!") wrote:
-
- >In article <walkerj-1710942341460001@192.0.2.1>,
- >walkerj@math.scarolina.edu (James W. Walker) wrote:
- >
- >>I guess I didn't make it clear in my original post, but it's not *my* code
- >>that gets stuck in SyncWait. It's usually Internet apps like Anarchie.
- >
- >For reliable program (like Anarchie :) disappearing into SyncWait normally
- >means that your networking on your machine is stuffed up somehow.
- >
- >To get out try this in MacsBug...
- >
- > sm a0+10 ffff
- > g
- >
- >What it does is set the ioResult field of the paramblock to -1, indicating
- >an error. You often have to do it a *lot* of times before it comes back
- >and often it doesn't work at all. But it makes you feel like you've got
- >control (:
-
- Ouch! OUCH! This is assuming that reg A0 really points to the
- cntrlParamBlockRec, which I hate to say doesn't always! I recently ran
- into a vSyncWait problem (on an 8100av) that lead to fingering the
- offending driver by looking at the data moved off D2 and matching that as
- a DCE entry with the help of Macsbug's 'drvr' dcmd. In every case of
- vSyncWait hang, a0 WAS NOT pointing to a valid paramblock so do a
-
- dm a0 cntrlparamblockrec
-
- before the 'sm' and make sure it looks like a valid paramblock, or you'll
- surely be rebooting thereafter.
-
- dEVoN
-
- - -----------------------------------------------------------------------
- Devon Hubbard Silicon Pilot
- devon_hubbard@taligent.com Taligent, Inc
-
- ---------------------------
-
- >From macrshap@bbn.com (Richard Shapiro)
- Subject: having trouble with AEInteractWithUser & drag manager
- Date: 9 Oct 1994 17:09:27 GMT
- Organization: Bolt, Beranek and Newman Inc.
-
- I'm in the process of adding some drag-support to an application. It's
- working ok when the application is selected, so the underlying drag
- management seems fine. But usually, I want to drag when another
- application is selected (ie I'll be dragging from that other application).
- In this case, when my app receives the drag, it needs to interact with the
- user before proceeding. This is where I'm stuck.
-
- I've set the InteractionAllowed flag to kAEInteractWithLocal (the default,
- I know, but I thought I'd be explicit), and I carefully call
- AEInteractWithUser before attempting any interaction. I'm calling it
- without a timeout (kNoTimeOut), without a notification rec (should be OK
- since I have the relevant BNDL, FREF and ICN# resources defined), and with
- a very simple idle procedure which essentially does nothing (since at the
- moment nothing in my app cares about update or activate events).
-
- What I expected to happen was the usual flashing in the
- current-application icon (on the right edge of the menubar), which would
- allow me to bring my app to the front. What actually happens is...nothing:
- no flashing, no process paying attention to mouse clicks, hence no way to
- select my application (which has received the drop and is waiting in the
- call to AEInteractWithUser) so that I can interact with it. All I can do
- is cmd-opt-escape to force a quit.
-
- What am I doing wrong? I'm assuming it must be one of two things: either
- it's illegal to have user interaction after receiving a drop but before
- acknowledging receipt; or I need to handle something in my idle function
- which I'm not currently handling.
-
- Any suggestions? If it matters, I'm using CW 4.5 C, and running System 7.1
- on a q660av with drag extensions and the drag-ware Finder (7.1.3). The
- drag flavors I'm handling at the moment are 'hfs ' and 'TEXT'.
-
- Please copy followups to email -- thanks.
-
- --
- rs/macrshap@bbn.com
-
- +++++++++++++++++++++++++++
-
- >From Jens Alfke <jens_alfke@powertalk.apple.com>
- Date: Mon, 10 Oct 1994 22:12:55 GMT
- Organization: Apple Computer
-
- Richard Shapiro, macrshap@bbn.com writes:
- > What am I doing wrong? I'm assuming it must be one of two things: either
- > it's illegal to have user interaction after receiving a drop but before
- > acknowledging receipt
-
- Bingo -- more specifically, it's illegal to cause a process switch while
- inside a drag handler, since the drag handlers are called via a lightweight
- process switch that is not compatible with the regular kind of process
- switch. While you're in a drag handler, WNE is hacked to do nothing for
- compatibility, but other ways to interact (such as calling AEInteractWithUser
- or SetFrontProcess) will choke your machine.
-
- Moral: Wait until after the drag finishes to try to interact with the user.
-
- --Jens Alfke jens_alfke@powertalk.apple.com
- "A man, a plan, a yam, a can of Spam ... Bananama!"
-
- +++++++++++++++++++++++++++
-
- >From macrshap@bbn.com (Richard Shapiro)
- Date: 11 Oct 1994 01:54:10 GMT
- Organization: Bolt, Beranek and Newman Inc.
-
- In article <1994Oct10.221255.26429@gallant.apple.com>, Jens Alfke
- <jens_alfke@powertalk.apple.com> wrote:
-
- > Bingo -- more specifically, it's illegal to cause a process switch while
- > inside a drag handler, since the drag handlers are called via a lightweight
- > process switch that is not compatible with the regular kind of process
- > switch. While you're in a drag handler, WNE is hacked to do nothing for
- > compatibility, but other ways to interact (such as calling
- AEInteractWithUser
- > or SetFrontProcess) will choke your machine.
- >
- > Moral: Wait until after the drag finishes to try to interact with the user.
-
- OK, I eventually came to that conclusion myself. I guess it's good to have
- it validated...
-
- Problem is, I really need user interaction to complete the processing of
- the drop. So, I tried to get around it by stashing the DragReference in a
- global, setting a flag, returning from the handler, and then dealing with
- the stashed DragReference when I'm back in the main event loop (depending
- on the flag, of course). This doesn't work either. I can interact with the
- user, but it looks as though the information associated with the
- DragReference vanishes once the handler is exited. At least, I can't get
- CountDragItems and the like to work properly outside the handler context.
- Are these supposed to work outside the handler?
-
- That seems to leave me with one final option: I have to get *all* the data
- out of the DragReference while I'm in the handler, stash the whole pile
- somewhere, exit the handler, and process the data later. Yucch, that's
- pretty awful. Is there another possibility I'm missing here?
-
- For now, I "fixed" the application to run without user-interaction when it
- isn't in the foreground (which can only happen as a result of a drop).
- It's better than nothing, but really not what I want...
-
- --
- rs/macrshap@bbn.com
-
- +++++++++++++++++++++++++++
-
- >From Jens Alfke <jens_alfke@powertalk.apple.com>
- Date: Tue, 11 Oct 1994 17:28:36 GMT
- Organization: Apple Computer
-
- Richard Shapiro, macrshap@bbn.com writes:
- > That seems to leave me with one final option: I have to get *all* the data
- > out of the DragReference while I'm in the handler, stash the whole pile
- > somewhere, exit the handler, and process the data later. Yucch, that's
- > pretty awful. Is there another possibility I'm missing here?
-
- Since you can't possibly use the DragReference after the sender disposes of
- it, I think this is your only option. Is it that bad? Get the data you want
- to use, stash it somewhere temporary, and when you get back into your event
- loop ask the user what to do with it.
-
- --Jens Alfke jens_alfke@powertalk.apple.com
- "A man, a plan, a yam, a can of Spam ... Bananama!"
-
- +++++++++++++++++++++++++++
-
- >From macrshap@bbn.com (Richard Shapiro)
- Date: 11 Oct 1994 22:25:03 GMT
- Organization: Bolt, Beranek and Newman Inc.
-
- In article <1994Oct11.172836.17257@gallant.apple.com>, Jens Alfke
- <jens_alfke@powertalk.apple.com> wrote:
-
-
- > Since you can't possibly use the DragReference after the sender disposes of
- > it
-
- As expected.
-
- > I think this is your only option. Is it that bad? Get the data you want
- > to use, stash it somewhere temporary, and when you get back into your event
- > loop ask the user what to do with it.
-
- No, it's not as bad as I thought. In fact it's already done and the result
- is cleaner than my original plan :)
-
- Now on to my next drag-manager question: receiving promise-hfs drags in an
- application other than the Finder. Details in another posting...
-
- --
- rs/macrshap@bbn.com
-
- +++++++++++++++++++++++++++
-
- >From leonardr@netcom.com (Leonard Rosenthol)
- Date: Wed, 19 Oct 1994 22:01:35 GMT
- Organization: Aladdin Systems, Inc.
-
- In article <macrshap-1110941825500001@ipa.bbn.com>, macrshap@bbn.com
- (Richard Shapiro) wrote:
-
- > > I think this is your only option. Is it that bad? Get the data you want
- > > to use, stash it somewhere temporary, and when you get back into your
- event
- > > loop ask the user what to do with it.
- >
- > No, it's not as bad as I thought. In fact it's already done and the result
- > is cleaner than my original plan :)
- >
- What I've been doing in this case is to get all the info from the Drag,
- and then send it back to myself in an Apple event (but NOT in sendToSelf
- mode). This works quite nicely...
-
-
- Leonard
- - ------------------------------------------------------------------------
- Leonard Rosenthol Internet: leonardr@netcom.com
- Director of Advanced Technology AppleLink: MACgician
- Aladdin Systems, Inc. GEnie: MACgician
-
- +++++++++++++++++++++++++++
-
- >From jonpugh@netcom.com (Jon Pugh)
- Date: Wed, 26 Oct 1994 07:08:53 GMT
- Organization: Will hack for food
-
- Leonard Rosenthol (leonardr@netcom.com) wrote:
- > What I've been doing in this case is to get all the info from the Drag,
- > and then send it back to myself in an Apple event (but NOT in sendToSelf
- > mode). This works quite nicely...
-
- I actually send the event twice. Once to myself as record only, and then
- again with signature addressing so that it goes through the event loop.
- That way you can record the event too.
-
- Jon
-
-
- ---------------------------
-
- End of C.S.M.P. Digest
- **********************
-
-
- ---------------------------------------------------------------------
-
- NOTE: The following Macintosh file(s) are enclosed with this
- message, in BinHex format. If your mail system does not convert
- BinHex files automatically, you will need to transfer the message to
- a Mac and run the BinHex application to decode it.
-
- Filename: KillIO dcmd.sit Size: 3181 bytes
-
- ---------------------------------------------------------------------
-
- (This file must be converted with BinHex 4.0)
-
-
-